1 /*
2 This is commands.cpp
3
4 Coxeter version 3.0 Copyright (C) 2002 Fokko du Cloux
5 See file main.cpp for full copyright notice
6 */
7
8 #include "commands.h"
9
10 #include "directories.h"
11 #include "error.h"
12 #include "fcoxgroup.h"
13 #include "help.h"
14 #include "interactive.h"
15 #include "special.h"
16 #include "typeA.h"
17
18 namespace commands {
19 using namespace directories;
20 using namespace error;
21 using namespace fcoxgroup;
22 using namespace help;
23 using namespace interactive;
24 };
25
26 namespace {
27
28 using namespace commands;
29 using namespace stack;
30
31 bool wgraph_warning = true;
32
33 /* used in the definition of command trees */
34
35 struct Empty_tag {};
36 struct Interface_tag {};
37 struct Main_tag {};
38 struct Uneq_tag {};
39
40 Stack<CommandTree *> treeStack;
41 CoxGroup* W = 0;
42
43 void activate(CommandTree* tree);
44 void ambigAction(CommandTree* tree, const String& str);
45 CommandData* ambigCommand();
46 void cellCompletion(DictCell<CommandData>* cell);
47 void commandCompletion(DictCell<CommandData>* cell);
48 void empty_error(char* str);
49 CommandTree* emptyCommandTree();
50 template<class C> CommandTree* initCommandTree();
51 void printCommandTree(FILE* file, DictCell<CommandData>* cell);
52 void startup();
53
54 void interface_entry();
55 void interface_exit();
56
57 void main_entry();
58 void main_exit();
59
60 void uneq_entry();
61 void uneq_exit();
62
63 void author_f();
64 void betti_f();
65 void coatoms_f();
66 void compute_f();
67 void descent_f();
68 void duflo_f();
69 void extremals_f();
70 void fullcontext_f();
71 void help_f();
72 void ihbetti_f();
73 void inorder_f();
74 void interface_f();
75 void interval_f();
76 void invpol_f();
77 void klbasis_f();
78 void lcorder_f();
79 void lcells_f();
80 void lcwgraphs_f();
81 void lrcorder_f();
82 void lrcells_f();
83 void lrcwgraphs_f();
84 void lrwgraph_f();
85 void lwgraph_f();
86 void matrix_f();
87 void mu_f();
88 void not_implemented_f();
89 void pol_f();
90 void q_f();
91 void qq_f();
92 void rank_f();
93 void rcorder_f();
94 void rcells_f();
95 void rcwgraphs_f();
96 void rwgraph_f();
97 void schubert_f();
98 void show_f();
99 void showmu_f();
100 void slocus_f();
101 void sstratification_f();
102 void type_f();
103 void uneq_f();
104
105 const char* author_tag = "prints a message about the author";
106 const char* betti_tag = "prints the ordinary betti numbers";
107 const char* coatoms_tag = "prints out the coatoms of an element";
108 const char* compute_tag = "prints out the normal form of an element";
109 const char* descent_tag = "prints out the descent sets";
110 const char* duflo_tag = "prints out the Duflo involutions";
111 const char* extremals_tag =
112 "prints out the k-l polynomials for the extremal pairs";
113 const char* fullcontext_tag = "sets the context to the full group";
114 const char* help_tag = "enters help mode";
115 const char* ihbetti_tag = "prints the IH betti numbers";
116 const char* input_tag = "(in help mode only) explains the input conventions";
117 const char* interface_tag = "changes the interface";
118 const char* interval_tag = "prints an interval in the Bruhat ordering";
119 const char* intro_tag =
120 "(in help mode only) prints a message for first time users";
121 const char* inorder_tag = "tells whether two elements are in Bruhat order";
122 const char* invpol_tag = "prints a single inverse k-l polynomial";
123 const char* klbasis_tag = "prints an element of the k-l basis";
124 const char* lcorder_tag = "prints the left cell order";
125 const char* lcells_tag = "prints out the left k-l cells";
126 const char* lcwgraphs_tag = "prints out the W-graphs of the left k-l cells";
127 const char* lrcorder_tag = "prints the two-sided cell order";
128 const char* lrcells_tag = "prints out the tow-sided k-l cells";
129 const char* lrcwgraphs_tag =
130 "prints out the W-graphs of the two-sided k-l cells";
131 const char* lrwgraph_tag = "prints out the two-sided W-graph";
132 const char* lwgraph_tag = "prints out the left W-graph";
133 const char* matrix_tag = "prints the current Coxeter matrix";
134 const char* mu_tag = "prints a single mu-coefficient";
135 const char* pol_tag = "prints a single k-l polynomial";
136 const char* q_tag = "exits the current mode";
137 const char* qq_tag = "exits the program";
138 const char* rank_tag = "resets the rank";
139 const char* rcorder_tag = "prints the right cell order";
140 const char* rcells_tag = "prints out the right k-l cells";
141 const char* rcwgraphs_tag = "prints out the W-graphs of the right k-l cells";
142 const char* rwgraph_tag = "prints out the right W-graph";
143 const char* schubert_tag = "prints out the kl data for a schubert variety";
144 const char* show_tag = "maps out the computation of a k-l polynomial";
145 const char* showmu_tag = "maps out the computation of a mu coefficient";
146 const char* slocus_tag =
147 "prints the rational singular locus of the Schubert variety";
148 const char* sstratification_tag =
149 "prints the rational singular stratification of the Schubert variety";
150 const char* type_tag =
151 "resets the type and rank (hence restarts the program)";
152 const char* uneq_tag = "puts the program in unequal-parameter mode";
153
154 namespace uneq {
155 void klbasis_f();
156 void lcorder_f();
157 void lrcorder_f();
158 void lcells_f();
159 void lrcells_f();
160 void mu_f();
161 void pol_f();
162 void rcells_f();
163 void rcorder_f();
164
165 const char* lcorder_tag = "prints the left cell order";
166 const char* lrcorder_tag = "prints the two-sided cell order";
167 const char* lcells_tag = "prints out the left k-l cells";
168 const char* lrcells_tag = "prints out the two-sided k-l cells";
169 const char* mu_tag = "prints out a mu-coefficient";
170 const char* pol_tag = "prints out a single k-l polynomial";
171 const char* rcells_tag = "prints out the right k-l cells";
172 const char* rcorder_tag = "prints the right cell order";
173 };
174 };
175
176 namespace commands {
177 void (*default_help)() = &help::default_h;
178 };
179
180 namespace commands {
181
182 namespace interface {
183
184 GroupEltInterface* in_buf = 0;
185
186 struct In_tag {};
187 struct Out_tag {};
188
189 void in_entry();
190 void in_exit();
191 void out_entry();
192 void out_exit();
193
194 void abort_f();
195 void alphabetic_f();
196 void bourbaki_f();
197 void default_f();
198 void decimal_f();
199 void gap_f();
200 void hexadecimal_f();
201 void in_f();
202 void out_f();
203 void permutation_f();
204 void symbol_f();
205 void terse_f();
206 void ordering_f();
207
208 const char* abort_tag = "leaves without modifying the interface";
209 const char* alphabetic_tag = "sets alphabetic generator symbols";
210 const char* bourbaki_tag = "sets Bourbaki conventions for i/o";
211 const char* decimal_tag = "sets decimal generator symbols";
212 const char* default_tag = "sets i/o to default mode";
213 const char* gap_tag = "sets i/o to GAP mode";
214 const char* hexadecimal_tag = "sets hexadecimal generator symbols";
215 const char* in_tag = "enters reset-input mode";
216 const char* out_tag = "enters reset-output mode";
217 const char* permutation_tag =
218 "sets permutation notation for i/o (in type A only)";
219 const char* ordering_tag = "modifies the ordering of the generators";
220 const char* terse_tag = "sets i/o to terse mode";
221
222 namespace in {
223 void alphabetic_f();
224 void bourbaki_f();
225 void decimal_f();
226 void default_f();
227 void gap_f();
228 void hexadecimal_f();
229 void permutation_f();
230 void postfix_f();
231 void prefix_f();
232 void separator_f();
233 void terse_f();
234 const char* alphabetic_tag =
235 "sets alphabetic generator symbols for input";
236 const char* bourbaki_tag = "sets Bourbaki conventions for input";
237 const char* decimal_tag = "sets decimal generator symbols for input";
238 const char* default_tag = "sets default conventions for input";
239 const char* gap_tag = "sets GAP conventions for input";
240 const char* hexadecimal_tag =
241 "sets hexadecimal generator symbols for input";
242 const char* permutation_tag =
243 "sets permutation notation for input (in type A only)";
244 const char* postfix_tag = "resets the input postfix";
245 const char* prefix_tag = "resets the input prefix";
246 const char* separator_tag = "resets the input separator";
247 const char* symbol_tag = "resets an input symbol";
248 const char* terse_tag = "sets terse conventions for input";
249 };
250
251 namespace out {
252 void alphabetic_f();
253 void bourbaki_f();
254 void decimal_f();
255 void default_f();
256 void gap_f();
257 void hexadecimal_f();
258 void permutation_f();
259 void postfix_f();
260 void prefix_f();
261 void separator_f();
262 void terse_f();
263 const char* alphabetic_tag =
264 "sets alphabetic generator symbols for output";
265 const char* bourbaki_tag = "sets Bourbaki conventions for output";
266 const char* decimal_tag = "sets decimal generator symbols for output";
267 const char* default_tag = "sets default conventions for output";
268 const char* gap_tag = "sets GAP conventions for output";
269 const char* hexadecimal_tag =
270 "sets hexadecimal generator symbols for output";
271 const char* permutation_tag =
272 "sets permutation notation for output (in type A only)";
273 const char* postfix_tag = "resets the output postfix";
274 const char* prefix_tag = "resets the output prefix";
275 const char* separator_tag = "resets the output separator";
276 const char* symbol_tag = "resets an output symbol";
277 const char* terse_tag = "sets terse conventions for output";
278 };
279 };
280
281 };
282
283 /*****************************************************************************
284
285 This module contains the code for the command interface. Although overall
286 I'm happy with the way it works, it suffers from a certain amount of
287 clumsiness.
288
289 The idea is that at each point in time, there is a certain active CommandTree
290 object. This is basically a dictionary of recognized command names, together
291 with the functions that will executed for them; in other words, something
292 that should be a map in STL parlance. Actually, the active command tree is
293 the top of the command tree stack treeStack; exiting the current mode means
294 popping the stack; entering a new mode means pushing it on the stack.
295
296 Each mode has an associated entry and exit function, which take care of
297 initialization and clean-up duties. Actually, there is mostly one main mode;
298 the entry function for this is the one which gets type and rank for the user;
299 the exit function destroys the current group. Redefining type or rank means
300 exiting and re-entering the main mode. In addition, there is the "empty"
301 mode, active on startup only, where nothing is defined yet, and some
302 auxiliary modes which temporarily hide the main mode in order to perform
303 certain duties : interface mode to set the i/o preferences of the user,
304 help mode for help, and also unequal-parameter mode which sets unequal
305 parameters for the k-l functions; this is in fact a sort of duplicate
306 main mode.
307
308 Command completion is implemented to the extend that incomplete commands
309 are recognized when non-ambiguous.
310
311 *****************************************************************************/
312
313 /*****************************************************************************
314
315 Chapter I -- Running the program
316
317 This section contains the following functions :
318
319 - ambigAction(str) : what to do with an ambiguous command;
320 - mainCommandTree() : returns a pointer to the initial command tree (and
321 builds it on first call);
322 - relax_f() : does nothing;
323 - run() : runs an interactive session;
324
325 *****************************************************************************/
326
327 namespace commands {
328
relax_f()329 void relax_f()
330
331 /*
332 Does nothing.
333 */
334
335 {}
336
run()337 void run()
338
339 /*
340 This function runs an interactive session of the program.
341 */
342
343 {
344 static String name(0);
345
346 activate(emptyCommandTree());
347
348 if (ERRNO) {
349 Error (ERRNO);
350 return;
351 }
352
353 while (1) { /* the only way to exit from this loop is the "qq" command */
354 CommandTree* tree = treeStack.top();
355 tree->prompt();
356 getInput(stdin,name);
357 CommandData* cd = tree->find(name);
358 if (cd == 0) {
359 tree->error(name.ptr());
360 continue;
361 }
362 if (cd == ambigCommand()) {
363 ambigAction(tree,name);
364 continue;
365 }
366 cd->action();
367 if (cd->autorepeat) {
368 tree->setAction("",cd->action);
369 tree->setRepeat("",true);
370 }
371 else {
372 tree->setAction("",&relax_f);
373 tree->setRepeat("",false);
374 }
375 }
376 }
377
default_error(char * str)378 void default_error(char* str)
379
380 /*
381 Default response to an unknown command.
382 */
383
384 {
385 Error(COMMAND_NOT_FOUND,str);
386 return;
387 }
388
389 };
390
391 namespace {
392
activate(CommandTree * tree)393 void activate(CommandTree* tree)
394
395 /*
396 Puts the tree on top of treeStack, and executes the initialization function.
397
398 */
399
400 {
401 treeStack.push(tree);
402 tree->entry();
403
404 if (ERRNO) { /* an error occured during initialization */
405 Error(ERRNO);
406 treeStack.pop();
407 ERRNO = MODECHANGE_FAIL;
408 }
409
410 return;
411 }
412
ambigAction(CommandTree * tree,const String & str)413 void ambigAction(CommandTree* tree, const String& str)
414
415 /*
416 Response to ambiguous commands. Prints a warning and the list of possible
417 completions in the current tree on stderr.
418 */
419
420 {
421 static String name(0);
422 bool b = true;
423
424 print(stderr,str);
425 fprintf(stderr," : ambiguous (");
426 DictCell<CommandData>* cell = tree->findCell(str);
427 new(&name) String(str);
428 printExtensions(stderr,cell->left,name,b);
429 fprintf(stderr,")\n");
430
431 return;
432 }
433
empty_error(char * str)434 void empty_error(char* str)
435
436 {
437 CommandTree* tree = mainCommandTree();
438
439 CommandData* cd = tree->find(str);
440 if (cd == 0) {
441 default_error(str);
442 return;
443 }
444 if (cd == ambigCommand()) {
445 ambigAction(tree,str);
446 return;
447 }
448 activate(tree);
449 if (ERRNO) { /* something went wrong during initialization */
450 Error(ERRNO);
451 return;
452 }
453 /* type and rank are set at this point */
454 if ((cd != tree->find("type")) && (cd != tree->find("rank")))
455 cd->action();
456 if (cd->autorepeat) {
457 tree->setAction("",cd->action);
458 tree->setRepeat("",true);
459 }
460 else {
461 tree->setAction("",&relax_f);
462 tree->setRepeat("",false);
463 }
464 return;
465 }
466
startup()467 void startup()
468
469 /*
470 The response to the first carriage return. Sets the response to "help"
471 to a less verbose version, and starts up the program.
472 */
473
474 {
475 activate(mainCommandTree());
476
477 if (ERRNO)
478 Error(ERRNO);
479
480 return;
481 }
482
483 };
484
485 /*****************************************************************************
486
487 Chapter II -- The CommandTree class.
488
489 The purpose of a CommandTree is to get a command-name from the user (or
490 perhaps from a file), and execute the corresponding command. For this,
491 it maintains a tree of CommandCell s, one for each initial subword of
492 each recognized command. Each CommandCell knows which command it should
493 execute.
494
495 Recognizing initial subwords allows for command completion : when the
496 completion is unique, the command is executed as if the full name were
497 typed. When the completion is not unique, the function for ambiguous
498 commands is executed : as defined here, it prints the list of all possible
499 completions in the current tree, and prompts the user again.
500
501 The case of the empty command is special : either it does nothing, or,
502 for most commands, it repeats the previous command.
503
504 This setup supports the concept of mode : at all times, there is a current
505 command tree, and in some situations this will change : new commands can
506 become available, commands can change behaviour or can become unavailable.
507 Help mode is an example of this. Another example is the interface command,
508 which loads the interface mode tree, so that the user can set the various
509 i/o parameters.
510
511 NOTE : even though I like the actual behaviour of the setup, it is all
512 rather clumsy and should be re-done. The command tree could be replaced
513 with some associative container like map. The current behaviour could
514 be pretty much kept as is, until we include the functionalities of
515 readline.
516
517 The following functions are defined :
518
519 - constructors and destructors :
520
521 - CommandTree(prompt,a,entry,error,exit,h) : builds a command tree with
522 the given prompt, action a, help function h, given entry and exit
523 functions, and error function (called when a command is not found);
524 - ~CommandTree();
525
526 - accessors :
527
528 - prompt : prints the prompt;
529
530 - manipulators :
531
532 - add(name,tag,a,h,rep) : adds a command with the given name, tag (used
533 in the online help), action a, help-action h and repetition flag rep;
534 - setAction(str,a) : resets the action of the command for str;
535 - setRepeat(str,b) : resets the repetition flag of the command for b;
536
537 ******************************************************************************/
538
539 namespace commands {
540
CommandTree(const char * prompt,void (* a)(),void (* entry)(),void (* error)(char *),void (* exit)(),void (* h)())541 CommandTree::CommandTree(const char* prompt,
542 void (*a)(),
543 void (*entry)(),
544 void (*error)(char*),
545 void (*exit)(),
546 void (*h)())
547 :d_prompt(prompt), d_entry(entry), d_error(error), d_exit(exit)
548
549 /*
550 Initializes a command tree with the given prompt and action for the
551 empty command.
552 */
553
554 {
555 d_root->ptr = new CommandData("","",a,&relax_f,false);
556
557 if (h) { /* add help functionality */
558 d_help = new CommandTree("help",&cr_h,h);
559 d_help->add("q",q_tag,&q_f,0,false);
560 add("help",help_tag,&help_f,&help_h,false);
561 }
562 }
563
~CommandTree()564 CommandTree::~CommandTree()
565
566 /*
567 The memory allocated by a CommandTree object is hidden in the dictionary
568 and in the d_help pointer.
569 */
570
571 {
572 delete d_help;
573 }
574
575 /******** accessors *********************************************************/
576
prompt() const577 void CommandTree::prompt() const
578
579 /*
580 Prints the prompt for the command tree.
581 */
582
583 {
584 printf("%s : ",d_prompt.ptr());
585 }
586
587 /******** manipulators ******************************************************/
588
add(const char * name,const char * tag,void (* a)(),void (* h)(),bool rep)589 void CommandTree::add(const char* name, const char* tag, void (*a)(),
590 void (*h)(), bool rep)
591
592 /*
593 This function adds a new command to the tree, adding new cells as
594 necessary.
595 */
596
597 {
598 CommandData *cd = new CommandData(name,tag,a,h,rep);
599
600 insert(name,cd);
601 if (d_help && h) { /* add help functionality */
602 d_help->add(name,tag,h,0,false);
603 }
604 }
605
setAction(const char * str,void (* a)())606 void CommandTree::setAction(const char* str, void (*a)())
607
608 /*
609 Assuming that str is a fullname on the command tree, sets the response
610 to str to a.
611
612 NOTE : is a bit dangerous. Should work also when str is only a prefix.
613 */
614
615 {
616 CommandData* cd = find(str);
617 cd->action = a;
618
619 return;
620 }
621
setRepeat(const char * str,bool b)622 void CommandTree::setRepeat(const char* str, bool b)
623
624 /*
625 Assuming that str is a fullname on the command tree, sets the autorepeat
626 value of the corresponding command data structure to b.
627 */
628
629 {
630 CommandData* cd = find(str);
631 cd->autorepeat = b;
632
633 return;
634 }
635
636 };
637
638 /*****************************************************************************
639
640 Chapter III -- The CommandData class.
641
642 The CommandData structure collects the data associated to a given command
643 name. The function a defines the action associated with the command; the
644 function h defines the action associated with the command in help mode.
645 The flag b is set if the command should be repeated on a carriage return.
646
647 *****************************************************************************/
648
649 namespace commands {
650
CommandData(const char * const & str,const char * const & t,void (* a)(),void (* h)(),bool rep)651 CommandData::CommandData(const char* const& str, const char* const& t,
652 void (*a)(), void (*h)(), bool rep)
653 :name(str), tag(t), action(a), help(h), autorepeat(rep)
654
655 {}
656
~CommandData()657 CommandData::~CommandData()
658
659 /*
660 No memory is allocated directly
661 */
662
663 {}
664
665 };
666
667 /*****************************************************************************
668
669 Chapter IV -- Building the command tree
670
671 This section contains the functions used for the construction of the primary
672 command tree, i.e., the initialization of the command module.
673
674 The following functions are defined :
675
676 - ambigCommand() : returns a special value flagging ambiguous commands;
677 - cellCompletion(cell) : auxiliary to commandCompletion;
678 - commandCompletion(tree) : finishes off the command tree;
679 - emptyCommandTree() : returns a pointer to the initial command tree;
680 - initCommandTree<Empty_tag> : builds the empty command tree;
681 - initCommandTree<Interface_tag> : builds the interface command tree;
682 - initCommandTree<Main_tag> : builds the main command tree;
683 - initCommandTree<Uneq_tag> : builds the command tree for unequal parameters;
684 - interfaceCommandTree() : returns a pointer to the interface command tree;
685 - mainCommandTree() : returns a pointer to the main command tree;
686 - uneqCommandTree() : returns a pointer to the unequal-parameter command
687 tree;
688
689 *****************************************************************************/
690
691 namespace {
692
ambigCommand()693 CommandData* ambigCommand()
694
695 /*
696 Returns a dummy command cell which is a placeholder indicating that
697 ambigAction must be executed; this requires knowledge of where we are
698 in the command tree.
699 */
700
701 {
702 static CommandData cd("","",0,0,false);
703 return &cd;
704 }
705
cellCompletion(DictCell<CommandData> * cell)706 void cellCompletion(DictCell<CommandData>* cell)
707
708 /*
709 This function fills in the value fields of the cells which do not
710 correspond to full names. It is assumed that the tree is traversed
711 in infix (?) order, i.e. first visit left child, then cell, the right
712 child, so that all longer names are already visited. This allows to
713 fill in unique completions backwards, making thins easy.
714 */
715
716 {
717 if (cell->fullname == true)
718 return;
719
720 if (cell->uniquePrefix == false) { /* ambiguous */
721 cell->ptr = ambigCommand();
722 return;
723 }
724
725 if (cell->uniquePrefix == true) { /* unique completion */
726 cell->ptr = cell->left->value();
727 return;
728 }
729 }
730
commandCompletion(DictCell<CommandData> * cell)731 void commandCompletion(DictCell<CommandData>* cell)
732
733 /*
734 This function finishes up the command tree by implementing command
735 completion. This is done as follows. We traverse the command tree
736 from the root. If node.fullname is true, we do nothing. Otherwise,
737 if node.uniquePrefix is true, we set node.value to be equal to the
738 value of the unique completion of the string recognized by node in
739 the dictionary. If node.uniquePrefix is false, we set node.value
740 to ambigCommand().
741 */
742
743 {
744 if (cell == 0)
745 return;
746
747 commandCompletion(cell->left);
748 cellCompletion(cell);
749 commandCompletion(cell->right);
750 }
751
initCommandTree()752 template<> CommandTree* initCommandTree<Empty_tag>()
753
754 /*
755 This function builds the initial command tree of the program. The idea
756 is that all commands on the main command tree will be considered entry
757 commands, and so will do the necessary initialization. This is achieved
758 thru the special error function.
759 */
760
761 {
762 static CommandTree tree("coxeter",&startup,&relax_f,&empty_error,&relax_f,
763 &intro_h);
764
765 tree.add("author","author_tag",&author_f,&relax_f,false);
766 tree.add("qq",qq_tag,&qq_f,&qq_h,false);
767
768 commandCompletion(tree.root());
769
770 tree.helpMode()->add("intro",intro_tag,&intro_h,0,false);
771
772 commandCompletion(tree.helpMode()->root());
773
774 return &tree;
775 }
776
emptyCommandTree()777 CommandTree* emptyCommandTree()
778
779 /*
780 Returns a pointer to the initial command tree of the program, building it on
781 the first call.
782 */
783
784 {
785 static CommandTree* tree = initCommandTree<Empty_tag>();
786 return tree;
787 }
788
initCommandTree()789 template<> CommandTree* initCommandTree<Interface_tag>()
790
791 /*
792 This function builds the interface command tree; this makes available the
793 various little commands that are needed to reset the interface, and that
794 have no reason to be clogging up the main command tree.
795 */
796
797 {
798 static CommandTree tree("interface",&relax_f,&interface_entry,&default_error,
799 &interface_exit,&interface_help);
800
801 tree.add("alphabetic",commands::interface::alphabetic_tag,
802 &commands::interface::alphabetic_f,&help::interface::alphabetic_h);
803 tree.add("bourbaki",commands::interface::bourbaki_tag,
804 &commands::interface::bourbaki_f,&help::interface::bourbaki_h);
805 tree.add("decimal",commands::interface::decimal_tag,
806 &commands::interface::decimal_f,&help::interface::decimal_h);
807 tree.add("default",commands::interface::default_tag,
808 &commands::interface::default_f,&help::interface::default_h);
809 tree.add("gap",commands::interface::out::gap_tag,
810 &commands::interface::out::gap_f, &help::interface::gap_h);
811 tree.add("hexadecimal",commands::interface::hexadecimal_tag,
812 &commands::interface::hexadecimal_f,
813 &help::interface::hexadecimal_h);
814 tree.add("in",commands::interface::in_tag,&commands::interface::in_f,
815 help::interface::in_h,false);
816 tree.add("ordering",commands::interface::ordering_tag,
817 &commands::interface::ordering_f,help::interface::ordering_h,false);
818 tree.add("out",commands::interface::out_tag,&commands::interface::out_f,
819 help::interface::out_h,false);
820 tree.add("permutation",commands::interface::permutation_tag,
821 &commands::interface::permutation_f,
822 &help::interface::permutation_h);
823 tree.add("q",q_tag,&q_f,0,false);
824 tree.add("terse",commands::interface::out::terse_tag,
825 &commands::interface::out::terse_f, &help::interface::out::terse_h);
826
827 commandCompletion(tree.root());
828 commandCompletion(tree.helpMode()->root());
829
830 return &tree;
831 }
832
initCommandTree()833 template<> CommandTree* initCommandTree<commands::interface::In_tag>()
834
835 /*
836 This function builds the command tree for the input-modification mode.
837 */
838
839 {
840 using namespace commands::interface;
841
842 static CommandTree tree("in",&relax_f,&in_entry,&default_error,
843 &in_exit,&help::interface::in_help);
844
845 tree.add("q",q_tag,&q_f,0,false);
846
847 tree.add("abort",abort_tag,&abort_f,&help::interface::abort_h);
848 tree.add("alphabetic",in::alphabetic_tag,&in::alphabetic_f,
849 &help::interface::in::alphabetic_h,false);
850 tree.add("bourbaki",in::bourbaki_tag,&in::bourbaki_f,
851 &help::interface::in::bourbaki_h);
852 tree.add("decimal",in::decimal_tag,&in::decimal_f,
853 &help::interface::in::decimal_h,false);
854 tree.add("default",in::default_tag,&in::default_f,
855 &help::interface::in::default_h);
856 tree.add("gap",in::gap_tag,&in::gap_f,&help::interface::in::gap_h);
857 tree.add("hexadecimal",in::hexadecimal_tag,&in::hexadecimal_f,
858 &help::interface::in::hexadecimal_h,false);
859 tree.add("permutation",in::permutation_tag,&in::permutation_f,
860 &help::interface::in::permutation_h,false);
861 tree.add("postfix",in::postfix_tag,&in::postfix_f,
862 &help::interface::in::postfix_h);
863 tree.add("prefix",in::prefix_tag,&in::prefix_f,
864 &help::interface::in::prefix_h);
865 tree.add("separator",in::separator_tag,
866 &in::separator_f,&help::interface::in::separator_h);
867 tree.add("symbol",in::symbol_tag,&symbol_f,
868 &help::interface::in::symbol_h);
869 tree.add("terse",in::terse_tag,&in::terse_f,&help::interface::in::terse_h);
870
871 commandCompletion(tree.root());
872 commandCompletion(tree.helpMode()->root());
873
874 return &tree;
875 }
876
initCommandTree()877 template<> CommandTree* initCommandTree<commands::interface::Out_tag>()
878
879 /*
880 This function builds the command tree for the output-modification mode.
881 */
882
883 {
884 using namespace commands::interface;
885
886 static CommandTree tree("out",&relax_f,&out_entry,&default_error,
887 &out_exit,&help::interface::out_help);
888
889 tree.add("q",q_tag,&q_f,0,false);
890
891 tree.add("alphabetic",out::alphabetic_tag,&out::alphabetic_f,
892 &help::interface::out::alphabetic_h,false);
893 tree.add("bourbaki",out::bourbaki_tag,&out::bourbaki_f,
894 &help::interface::out::bourbaki_h);
895 tree.add("decimal",out::decimal_tag,&out::decimal_f,
896 &help::interface::out::decimal_h,false);
897 tree.add("default",out::default_tag,&out::default_f,
898 &help::interface::out::default_h);
899 tree.add("gap",out::gap_tag,&out::gap_f,
900 &help::interface::out::gap_h);
901 tree.add("hexadecimal",out::hexadecimal_tag,&out::hexadecimal_f,
902 &help::interface::out::hexadecimal_h,false);
903 tree.add("permutation",out::permutation_tag,&out::permutation_f,
904 &help::interface::out::permutation_h,false);
905 tree.add("postfix",out::postfix_tag,&out::postfix_f,
906 &help::interface::out::postfix_h);
907 tree.add("prefix",out::prefix_tag,&out::prefix_f,
908 &help::interface::out::prefix_h);
909 tree.add("separator",out::separator_tag,
910 &out::separator_f,&help::interface::out::separator_h);
911 tree.add("symbol",out::symbol_tag,&symbol_f,
912 &help::interface::out::symbol_h);
913 tree.add("terse",out::terse_tag,&out::terse_f,
914 &help::interface::out::terse_h);
915
916 commandCompletion(tree.root());
917 commandCompletion(tree.helpMode()->root());
918
919 return &tree;
920 }
921
922 };
923
924 namespace commands {
925
inCommandTree()926 CommandTree* interface::inCommandTree()
927
928 {
929 static CommandTree* tree = initCommandTree<In_tag>();
930 return tree;
931 }
932
outCommandTree()933 CommandTree* interface::outCommandTree()
934
935 {
936 static CommandTree* tree = initCommandTree<Out_tag>();
937 return tree;
938 }
939
interfaceCommandTree()940 CommandTree* interfaceCommandTree()
941
942 /*
943 Returns a pointer to the interface command tree, building it on the first
944 call.
945 */
946
947 {
948 static CommandTree* tree = initCommandTree<Interface_tag>();
949 return tree;
950 }
951
952 };
953
954 namespace {
955
initCommandTree()956 template<> CommandTree* initCommandTree<Main_tag>()
957
958 /*
959 This function builds the main command tree, the one that is being run on
960 startup. Auxiliary trees may be grafted onto this one (thru the pushdown
961 stack treeStack) by some functions needing to be in special modes.
962 */
963
964 {
965 static CommandTree tree("coxeter",&relax_f,&main_entry,&default_error,
966 &main_exit,&main_help);
967
968 tree.add("author",author_tag,&author_f,&relax_f,false);
969 tree.add("betti",betti_tag,&betti_f,&betti_h,false);
970 tree.add("coatoms",coatoms_tag,&coatoms_f,&coatoms_h);
971 tree.add("compute",compute_tag,&compute_f,&compute_h);
972 tree.add("descent",descent_tag,&descent_f,&descent_h);
973 tree.add("duflo",duflo_tag,&duflo_f,&duflo_h);
974 tree.add("extremals",extremals_tag,&extremals_f,&extremals_h);
975 tree.add("fullcontext",fullcontext_tag,&fullcontext_f,&fullcontext_h);
976 tree.add("ihbetti",ihbetti_tag,&ihbetti_f,&ihbetti_h,false);
977 tree.add("interface",interface_tag,&interface_f,&interface_h,false);
978 tree.add("interval",interval_tag,&interval_f,&interval_h,false);
979 tree.add("inorder",inorder_tag,&inorder_f,&inorder_h);
980 tree.add("invpol",invpol_tag,&invpol_f,&invpol_h);
981 tree.add("lcorder",lcorder_tag,&lcorder_f,&lcorder_h,false);
982 tree.add("lcells",lcells_tag,&lcells_f,&lcells_h,false);
983 tree.add("lcwgraphs",lcwgraphs_tag,&lcwgraphs_f,&lcwgraphs_h,false);
984 tree.add("lrcorder",lrcorder_tag,&lrcorder_f,&lrcorder_h,false);
985 tree.add("lrcells",lrcells_tag,&lrcells_f,&lrcells_h,false);
986 tree.add("lrcwgraphs",lrcwgraphs_tag,&lrcwgraphs_f,&lrcwgraphs_h,false);
987 tree.add("lrwgraph",lrwgraph_tag,&lrwgraph_f,&lrwgraph_h,false);
988 tree.add("lwgraph",lwgraph_tag,&lwgraph_f,&lwgraph_h,false);
989 tree.add("klbasis",klbasis_tag,&klbasis_f,&klbasis_h,true);
990 tree.add("matrix",matrix_tag,&matrix_f,&matrix_h);
991 tree.add("mu",mu_tag,&mu_f,&mu_h);
992 tree.add("pol",pol_tag,&pol_f,&pol_h);
993 tree.add("q",q_tag,&q_f,0,false);
994 tree.add("qq",qq_tag,&qq_f,&qq_h,false);
995 tree.add("rank",rank_tag,&rank_f,&rank_h,false);
996 tree.add("rcorder",rcorder_tag,&rcorder_f,&rcorder_h,false);
997 tree.add("rcells",rcells_tag,&rcells_f,&rcells_h,false);
998 tree.add("rcwgraphs",rcwgraphs_tag,&rcwgraphs_f,&rcwgraphs_h,false);
999 tree.add("rwgraph",rwgraph_tag,&rwgraph_f,&rwgraph_h,false);
1000 tree.add("schubert",schubert_tag,&schubert_f,&schubert_h);
1001 tree.add("show",show_tag,&show_f,&show_h);
1002 tree.add("showmu",showmu_tag,&showmu_f,&showmu_h);
1003 tree.add("slocus",slocus_tag,&slocus_f,&slocus_h);
1004 tree.add("sstratification",sstratification_tag,&sstratification_f,
1005 &sstratification_h);
1006 tree.add("type",type_tag,&type_f,&type_h,false);
1007 tree.add("uneq",uneq_tag,&uneq_f,&uneq_h,false);
1008
1009 special::addSpecialCommands(&tree);
1010
1011 commandCompletion(tree.root());
1012
1013 tree.helpMode()->add("intro",intro_tag,&intro_h,0,false);
1014 tree.helpMode()->add("input",input_tag,&input_h,0,false);
1015
1016 commandCompletion(tree.helpMode()->root());
1017
1018 return &tree;
1019 }
1020
1021 };
1022
1023 namespace commands {
1024
mainCommandTree()1025 CommandTree* mainCommandTree()
1026
1027 /*
1028 Returns a pointer to the main command tree of the program, building it on
1029 the first call.
1030 */
1031
1032 {
1033 static CommandTree* tree = initCommandTree<Main_tag>();
1034 return tree;
1035 }
1036
1037 };
1038
1039 namespace {
1040
initCommandTree()1041 template<> CommandTree* initCommandTree<Uneq_tag>()
1042
1043 /*
1044 This function builds the unequal-parameter command tree. It contains
1045 essentially the same functions as the main command tree, except that the
1046 unequal-parameter versions have been substituted for the k-l functions.
1047 */
1048
1049 {
1050 static CommandTree tree("uneq",&relax_f,&uneq_entry,&default_error,
1051 &uneq_exit,&uneq_help);
1052
1053 tree.add("author",author_tag,&author_f,&relax_f,false);
1054 tree.add("coatoms",coatoms_tag,&coatoms_f,&coatoms_h);
1055 tree.add("compute",compute_tag,&compute_f,&compute_h);
1056 tree.add("descent",descent_tag,&descent_f,&descent_h);
1057 tree.add("fullcontext",fullcontext_tag,&fullcontext_f,&fullcontext_h);
1058 tree.add("interface",interface_tag,&interface_f,&interface_h,false);
1059 tree.add("klbasis",klbasis_tag,&uneq::klbasis_f,&help::uneq::klbasis_h,true);
1060 tree.add("lcorder",uneq::lcorder_tag,&uneq::lcorder_f,
1061 &help::uneq::lcorder_h,false);
1062 tree.add("lrcorder",uneq::lrcorder_tag,&uneq::lrcorder_f,
1063 &help::uneq::lrcorder_h,false);
1064 tree.add("lcells",uneq::lcells_tag,&uneq::lcells_f,&help::uneq::lcells_h,
1065 false);
1066 tree.add("lrcells",uneq::lrcells_tag,&uneq::lrcells_f,&help::uneq::lrcells_h,
1067 false);
1068 tree.add("matrix",matrix_tag,&matrix_f,&matrix_h);
1069 tree.add("mu",uneq::mu_tag,&uneq::mu_f,&help::uneq::mu_h);
1070 tree.add("pol",uneq::pol_tag,&uneq::pol_f,&help::uneq::pol_h);
1071 tree.add("rcells",uneq::rcells_tag,&uneq::rcells_f,&help::uneq::rcells_h,
1072 false);
1073 tree.add("rcorder",uneq::rcorder_tag,&uneq::rcorder_f,
1074 &help::uneq::rcorder_h,false);
1075 tree.add("q",q_tag,&q_f,0,false);
1076 tree.add("qq",qq_tag,&qq_f,&qq_h,false);
1077
1078 commandCompletion(tree.root());
1079 commandCompletion(tree.helpMode()->root());
1080
1081 return &tree;
1082 }
1083
1084 };
1085
1086 namespace commands {
1087
uneqCommandTree()1088 CommandTree* uneqCommandTree()
1089
1090 /*
1091 Returns a pointer to the uneq command tree, building it on the first call.
1092 */
1093
1094 {
1095 static CommandTree* tree = initCommandTree<Uneq_tag>();
1096 return tree;
1097 }
1098
1099 };
1100
1101 /*****************************************************************************
1102
1103 Chapter V -- Functions for the predefined commands.
1104
1105 This section contains the functions defining the responses to the various
1106 commands which are provided by the program. The functions are placed in
1107 the unnamed namespace defined in this file.
1108
1109 The following functions are defined :
1110
1111 - author_f() : response to "author";
1112 - betti_f() : response to "betti";
1113 - coatoms_f() : response to "coatoms";
1114 - compute_f() : response to "compute";
1115 - descent_f() : response to "descent";
1116 - duflo_f() : response to "duflo";
1117 - extremals_f() : response to "extremals";
1118 - fullcontext_f() : response to "fullcontext";
1119 - ihbetti_f() : response to "ihbetti";
1120 - inorder_f() : response to "inorder";
1121 - interface_f() : response to "interface";
1122 - help_f() : repsonse to "help";
1123 - klbasis_f() : response to "klbasis";
1124 - lcorder_f() : response to "lcorder";
1125 - lcells_f() : response to "lcells";
1126 - lcwgraphs_f() : response to "lcwgraphs";
1127 - lrcorder_f() : response to "lrcorder";
1128 - lrcells_f() : response to "lrcells";
1129 - lrcwgraphs_f() : response to "lrcwgraphs";
1130 - lrwgraph_f() : response to "lrwgraph";
1131 - lwgraph_f() : response to "lwgraph";
1132 - matrix_f() : response to "matrix";
1133 - mu_f() : response to "mu";
1134 - not_implemented_f() : response for not (yet) implemented features;
1135 - q_f() : response to "q";
1136 - qq_f() : response to "qq";
1137 - rank_f() : response to "rank";
1138 - rcorder_f() : response to "rcorder";
1139 - rcells_f() : response to "rcells";
1140 - rcwgraphs_f() : response to "rcwgraphs";
1141 - rwgraph_f() : response to "rwgraph";
1142 - relax_f() : does nothing;
1143 - schubert_f() : response to "schubert";
1144 - show_f() : response to "show";
1145 - showmu_f() : response to "showmu";
1146 - slocus_f() : response to "slocus";
1147 - sstratification_f() : response to "sstratification";
1148 - type_f() : response to "type";
1149 - uneq_f() : response to "uneq";
1150
1151 In uneq mode :
1152
1153 - klbasis_f() : response to "klbasis";
1154 - lcorder_f() : response to "lcorder";
1155 - lcells_f() : response to "lcells";
1156 - lrcorder_f() : response to "lrcorder";
1157 - lrcells_f() : response to "lrcells";
1158 - mu_f() : response to "mu";
1159 - pol_f() : response to "pol";
1160 - rcells_f() : response to "rcells";
1161 - rcorder_f() : response to "rcorder";
1162
1163 In interface mode :
1164
1165 - abort_f() : aborts input interface modification;
1166 - alphabetic_f() : sets alphabetic generator symbols;
1167 - bourbaki_f() : sets bourbaki conventions;
1168 - decimal_f() : sets decimal generator symbols;
1169 - default_f() : sets default i/o;
1170 - gap_f() : sets GAP-style i/o;
1171 - hexadecimal_f() : sets hexadecimal generator symbols;
1172 - ordering_f() : changes the ordering of the generators;
1173 - symbol_f() : resets generator symbol;
1174 - terse_f() : sets terse style i/o;
1175 - in::alphabetic_f() : sets alphabetic generator symbols;
1176 - in::bourbaki_f() : sets bourbaki conventions;
1177 - in::decimal_f() : sets decimal generator symbols;
1178 - in::default_f() : sets default-style input;
1179 - in::gap_f() : sets GAP-style input;
1180 - in::hexadecimal_f() : sets hexadecimal generator symbols;
1181 - in::permutation_f() : sets permutation input;
1182 - in::postfix_f() : resets input postfix;
1183 - in::prefix_f() : resets input prefix;
1184 - in::separator_f() : resets input separator;
1185 - in::terse_f() : sets terse-style input;
1186 - out::alphabetic_f() : sets alphabetic generator symbols;
1187 - out::bourbaki_f() : sets bourbaki conventions;
1188 - out::decimal_f() : sets decimal generator symbols;
1189 - out::default_f() : sets default-style output;
1190 - out::gap_f() : sets GAP-style output;
1191 - out::hexadecimal_f() : sets hexadecimal generator symbols;
1192 - out::permutation_f() : sets permutation output;
1193 - out::postfix_f() : resets output postfix;
1194 - out::prefix_f() : resets output prefix;
1195 - out::separator_f() : resest output separator;
1196 - out::terse_f() : sets terse-style output;
1197
1198 *****************************************************************************/
1199
1200 namespace {
1201
author_f()1202 void author_f()
1203
1204 /*
1205 Prints a message about the author.
1206 */
1207
1208 {
1209 printFile(stderr,"author.mess",MESSAGE_DIR);
1210 return;
1211 }
1212
betti_f()1213 void betti_f()
1214
1215 /*
1216 Prints out the ordinary betti numbers of [e,y].
1217
1218 NOTE : could be *much* improved! In particular, we would want to have
1219 betti(x,y) for x <= y.
1220 */
1221
1222 {
1223 static CoxWord g(0);
1224
1225 printf("enter your element (finish with a carriage return) :\n");
1226 g = interactive::getCoxWord(W);
1227 if (ERRNO) {
1228 Error(ERRNO);
1229 return;
1230 }
1231
1232 CoxNbr y = W->extendContext(g);
1233 if (ERRNO) {
1234 Error(ERRNO);
1235 return;
1236 }
1237
1238 OutputTraits& traits = W->outputTraits();
1239 printBetti(stdout,y,W->schubert(),traits);
1240
1241 return;
1242 }
1243
coatoms_f()1244 void coatoms_f()
1245
1246 /*
1247 Prints out the coatoms of a given element, computing them in elementary
1248 fashion.
1249 */
1250
1251 {
1252 static CoxWord g(0);
1253
1254 printf("enter your element (finish with a carriage return) :\n");
1255 g = interactive::getCoxWord(W);
1256 if (ERRNO) {
1257 Error(ERRNO);
1258 return;
1259 }
1260
1261 List<CoxWord> c(0);
1262 W->coatoms(c,g);
1263
1264 for (Ulong j = 0; j < c.size(); ++j) {
1265 W->print(stdout,c[j]);
1266 printf("\n");
1267 }
1268
1269 return;
1270 }
1271
compute_f()1272 void compute_f()
1273
1274 /*
1275 Gets an element from the user, and prints out its normal form.
1276 */
1277
1278 {
1279 static CoxWord g(0);
1280
1281 printf("enter your element (finish with a carriage return) :\n");
1282 g = interactive::getCoxWord(W);
1283 if (ERRNO) {
1284 Error(ERRNO);
1285 return;
1286 }
1287 W->normalForm(g);
1288 W->print(stdout,g);
1289 if (SmallCoxGroup* Ws = dynamic_cast<SmallCoxGroup*> (W)) {
1290 CoxNbr x = 0;
1291 Ws->prodD(x,g);
1292 printf(" (#%lu)",static_cast<Ulong>(x));
1293 }
1294 CoxNbr x = W->contextNumber(g);
1295 if (x != undef_coxnbr)
1296 printf(" (%s%lu)","%",static_cast<Ulong>(x));
1297 printf("\n");
1298
1299 return;
1300 }
1301
descent_f()1302 void descent_f()
1303
1304 /*
1305 Prints the left and right descent sets.
1306 */
1307
1308 {
1309 static CoxWord g(0);
1310
1311 printf("enter your element (finish with a carriage return) :\n");
1312 g = interactive::getCoxWord(W);
1313 if (ERRNO) {
1314 Error(ERRNO);
1315 return;
1316 }
1317
1318 LFlags f = W->ldescent(g);
1319 printf("L:");
1320 W->printFlags(stdout,f);
1321 printf("; R:");
1322 f = W->rdescent(g);
1323 W->printFlags(stdout,f);
1324 printf("\n");
1325
1326 return;
1327 }
1328
duflo_f()1329 void duflo_f()
1330
1331 /*
1332 Prints the Duflo involutions. Works for finite groups only.
1333 */
1334
1335 {
1336 if (!isFiniteType(W)) {
1337 printFile(stderr,"duflo.mess",MESSAGE_DIR);
1338 return;
1339 }
1340
1341 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
1342
1343 Wf->fullContext();
1344 if (ERRNO) {
1345 Error(ERRNO);
1346 return;
1347 }
1348
1349 Wf->fillMu();
1350 if (ERRNO) {
1351 Error(ERRNO);
1352 return;
1353 }
1354
1355 OutputFile file;
1356 OutputTraits& traits = Wf->outputTraits();
1357
1358 printHeader(file.f(),dufloH,traits);
1359 printDuflo(file.f(),Wf->duflo(),Wf->lCell(),Wf->kl(),W->interface(),traits);
1360
1361 return;
1362 }
1363
extremals_f()1364 void extremals_f()
1365
1366 /*
1367 Prints out the list of extremal elements x <= y (this is part of the schubert
1368 command.
1369 */
1370
1371 {
1372 static CoxWord g(0);
1373
1374 printf("Enter your element (finish with a carriage-return) :\n");
1375 g = interactive::getCoxWord(W);
1376 if (ERRNO) {
1377 Error(ERRNO);
1378 return;
1379 }
1380
1381 CoxNbr y = W->extendContext(g);
1382 if (ERRNO) {
1383 Error(ERRNO);
1384 return;
1385 }
1386
1387 interactive::OutputFile file;
1388 OutputTraits& traits = W->outputTraits();
1389
1390 printHeader(file.f(),extremalsH,traits);
1391 printExtremals(file.f(),y,W->kl(),W->interface(),traits);
1392
1393 return;
1394 }
1395
fullcontext_f()1396 void fullcontext_f()
1397
1398 /*
1399 Response to the fullcontext command. This sets the context to the full
1400 group. Of course, it works only for finite groups.
1401 */
1402
1403 {
1404 if (!isFiniteType(W)) {
1405 printFile(stderr,"fullcontext.mess",MESSAGE_DIR);
1406 return;
1407 }
1408
1409 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
1410
1411 Wf->fullContext();
1412 if (ERRNO) {
1413 Error(ERRNO);
1414 }
1415
1416 return;
1417 }
1418
help_f()1419 void help_f()
1420
1421 /*
1422 Response to the help command.
1423 */
1424
1425 {
1426 activate(treeStack.top()->helpMode());
1427 return;
1428 }
1429
ihbetti_f()1430 void ihbetti_f()
1431
1432 /*
1433 Prints out the IH betti numbers of [e,y].
1434 */
1435
1436 {
1437 static CoxWord g(0);
1438
1439 printf("enter your element (finish with a carriage return) :\n");
1440 g = interactive::getCoxWord(W);
1441 if (ERRNO) {
1442 Error(ERRNO);
1443 return;
1444 }
1445
1446 CoxNbr y = W->extendContext(g);
1447 if (ERRNO) {
1448 Error(ERRNO);
1449 return;
1450 }
1451
1452 OutputTraits& traits = W->outputTraits();
1453 printIHBetti(stdout,y,W->kl(),traits);
1454
1455 return;
1456 }
1457
interface_f()1458 void interface_f()
1459
1460 /*
1461 Response to the interface command.
1462 */
1463
1464 {
1465 activate(interfaceCommandTree());
1466 return;
1467 }
1468
interval_f()1469 void interval_f()
1470
1471 /*
1472 Response to the interval command.
1473 */
1474
1475 {
1476 CoxWord g(0);
1477 CoxWord h(0);
1478
1479 fprintf(stdout,"first : ");
1480 g = interactive::getCoxWord(W);
1481 if (ERRNO) {
1482 Error(ERRNO);
1483 return;
1484 }
1485 fprintf(stdout,"second : ");
1486 h = interactive::getCoxWord(W);
1487 if (ERRNO) {
1488 Error(ERRNO);
1489 return;
1490 }
1491
1492 if (not W->inOrder(g,h)) {
1493 fprintf(stderr,"the two elements are not in order\n");
1494 return;
1495 }
1496
1497 W->extendContext(h);
1498
1499 CoxNbr x = W->contextNumber(g);
1500 CoxNbr y = W->contextNumber(h);
1501
1502 OutputFile file;
1503
1504 BitMap b(W->contextSize());
1505 W->extractClosure(b,y);
1506
1507 BitMap::ReverseIterator b_rend = b.rend();
1508 List<CoxNbr> res(0);
1509
1510 for (BitMap::ReverseIterator i = b.rbegin(); i != b_rend; ++i)
1511 if (not W->inOrder(x,*i)) {
1512 BitMap bi(W->contextSize());
1513 W->extractClosure(bi,*i);
1514 CoxNbr z = *i; // andnot will invalidate iterator
1515 b.andnot(bi);
1516 b.setBit(z); // otherwise the decrement will not be correct
1517 } else
1518 res.append(*i);
1519
1520 schubert::NFCompare nfc(W->schubert(),W->ordering());
1521 Permutation a(res.size());
1522 sortI(res,nfc,a);
1523
1524 for (size_t j = 0; j < res.size(); ++j) {
1525 W->print(file.f(),res[a[j]]);
1526 fprintf(file.f(),"\n");
1527 }
1528
1529 return;
1530 }
1531
inorder_f()1532 void inorder_f()
1533
1534 /*
1535 Response to the inorder command. This will tell whether two elements
1536 are comparable in Bruhat order, using only the elementary string operations
1537 (and hence not consuming any memory.)
1538 */
1539
1540 {
1541 CoxWord g(0);
1542 CoxWord h(0);
1543 List<Length> a(0);
1544
1545 fprintf(stdout,"first : ");
1546 g = interactive::getCoxWord(W);
1547 if (ERRNO) {
1548 Error(ERRNO);
1549 return;
1550 }
1551 fprintf(stdout,"second : ");
1552 h = interactive::getCoxWord(W);
1553 if (ERRNO) {
1554 Error(ERRNO);
1555 return;
1556 }
1557
1558 if (W->inOrder(a,g,h)) {
1559 fprintf(stdout,"true : ");
1560 Ulong i = 0;
1561 for (Ulong j = 0; j < a.size(); ++j) {
1562 while (i < a[j]) {
1563 W->printSymbol(stdout,h[i]-1);
1564 ++i;
1565 }
1566 fprintf(stdout,".");
1567 ++i;
1568 }
1569 while (i < h.length()) {
1570 W->printSymbol(stdout,h[i]-1);
1571 ++i;
1572 }
1573 fprintf(stdout,"\n");
1574 }
1575 else
1576 fprintf(stdout,"false\n");
1577 }
1578
invpol_f()1579 void invpol_f()
1580
1581 /*
1582 Response to the invpol command. This prints out a single inverse k-l
1583 polynomial, without details.
1584 */
1585
1586 {
1587 CoxWord g(0);
1588
1589 fprintf(stdout,"first : ");
1590 g = interactive::getCoxWord(W);
1591 if (ERRNO) {
1592 Error(ERRNO);
1593 return;
1594 }
1595 CoxNbr x = W->extendContext(g);
1596 if (ERRNO) {
1597 Error(ERRNO);
1598 return;
1599 }
1600
1601 fprintf(stdout,"second : ");
1602 g = interactive::getCoxWord(W);
1603 if (ERRNO) {
1604 Error(ERRNO);
1605 return;
1606 }
1607 CoxNbr y = W->extendContext(g);
1608 if (ERRNO) {
1609 Error(ERRNO);
1610 return;
1611 }
1612
1613 if (!W->inOrder(x,y)) {
1614 fprintf(stderr,"the two elements are not in Bruhat order\n");
1615 return;
1616 }
1617
1618 const invkl::KLPol& pol = W->invklPol(x,y);
1619 if (ERRNO) {
1620 Error(ERRNO,x,y);
1621 return;
1622 }
1623
1624 print(stdout,pol,"q");
1625 printf("\n");
1626
1627 return;
1628 }
1629
klbasis_f()1630 void klbasis_f()
1631
1632 /*
1633 Prints out one element in the k-l basis of the group, in the format
1634 defined by the current output mode.
1635 */
1636
1637 {
1638 CoxWord g(0);
1639
1640 printf("enter your element (finish with a carriage return) :\n");
1641 g = interactive::getCoxWord(W);
1642 if (ERRNO) {
1643 Error(ERRNO);
1644 return;
1645 }
1646
1647 CoxNbr y = W->extendContext(g);
1648 if (ERRNO) {
1649 Error(ERRNO);
1650 return;
1651 }
1652
1653 kl::HeckeElt h(0);
1654
1655 W->cBasis(h,y);
1656 if (ERRNO) {
1657 Error(ERRNO);
1658 return;
1659 }
1660
1661 interactive::OutputFile file;
1662 OutputTraits& traits = W->outputTraits();
1663
1664 printHeader(file.f(),basisH,traits);
1665 printAsBasisElt(file.f(),h,W->schubert(),W->interface(),traits);
1666
1667 return;
1668 }
1669
lcorder_f()1670 void lcorder_f()
1671
1672 /*
1673 Prints the left cell order of the current group in a file. Works only for
1674 finite groups.
1675 */
1676
1677 {
1678 if (!isFiniteType(W)) {
1679 printFile(stderr,"lcorder.mess",MESSAGE_DIR);
1680 return;
1681 }
1682
1683 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
1684
1685 Wf->fullContext();
1686 if (ERRNO) {
1687 Error(ERRNO);
1688 return;
1689 }
1690
1691 Wf->fillMu();
1692 if (ERRNO) {
1693 Error(ERRNO);
1694 return;
1695 }
1696
1697 OutputFile file;
1698 OutputTraits& traits = Wf->outputTraits();
1699
1700 printHeader(file.f(),lCOrderH,traits);
1701 printLCOrder(file.f(),Wf->kl(),Wf->interface(),traits);
1702
1703 return;
1704 }
1705
lcells_f()1706 void lcells_f()
1707
1708 /*
1709 This function prints out the left cells in the group.
1710 */
1711
1712 {
1713 if (!isFiniteType(W)) {
1714 printFile(stderr,"lcells.mess",MESSAGE_DIR);
1715 return;
1716 }
1717
1718 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
1719
1720 OutputFile file;
1721 OutputTraits& traits = Wf->outputTraits();
1722
1723 printHeader(file.f(),lCellsH,traits);
1724 printLCells(file.f(),Wf->lCell(),Wf->kl(),Wf->interface(),traits);
1725
1726 return;
1727 }
1728
lcwgraphs_f()1729 void lcwgraphs_f()
1730
1731 /*
1732 This function prints out the W-graphs of the left cells in the group.
1733 It works only for finite groups currently.
1734 */
1735
1736 {
1737 if (!isFiniteType(W)) {
1738 printFile(stderr,"lcells.mess",MESSAGE_DIR);
1739 return;
1740 }
1741
1742 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
1743
1744 OutputFile file;
1745 OutputTraits& traits = Wf->outputTraits();
1746
1747 printHeader(file.f(),lCellWGraphsH,traits);
1748 printLCellWGraphs(file.f(),Wf->lCell(),Wf->kl(),W->interface(),traits);
1749
1750 return;
1751 }
1752
lrcorder_f()1753 void lrcorder_f()
1754
1755 /*
1756 Prints the two-sided cell order of the current group in a file. Works only
1757 for finite groups.
1758 */
1759
1760 {
1761 if (!isFiniteType(W)) {
1762 printFile(stderr,"lrcorder.mess",MESSAGE_DIR);
1763 return;
1764 }
1765
1766 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
1767
1768 Wf->fullContext();
1769 if (ERRNO) {
1770 Error(ERRNO);
1771 return;
1772 }
1773
1774 Wf->fillMu();
1775 if (ERRNO) {
1776 Error(ERRNO);
1777 return;
1778 }
1779
1780 OutputFile file;
1781 OutputTraits& traits = Wf->outputTraits();
1782
1783 printHeader(file.f(),lrCOrderH,traits);
1784 printLRCOrder(file.f(),Wf->kl(),Wf->interface(),traits);
1785
1786 return;
1787 }
1788
lrcells_f()1789 void lrcells_f()
1790
1791 /*
1792 This function prints out the two-sided cells in the group, together with the
1793 corresponding W-graphs. Works only for finite groups.
1794 */
1795
1796 {
1797 if (!isFiniteType(W)) {
1798 printFile(stderr,"lrcells.mess",MESSAGE_DIR);
1799 return;
1800 }
1801
1802 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
1803
1804 Wf->fullContext();
1805 if (ERRNO) {
1806 Error(ERRNO);
1807 return;
1808 }
1809
1810 Wf->fillMu();
1811 if (ERRNO) {
1812 Error(ERRNO);
1813 return;
1814 }
1815
1816 OutputFile file;
1817 OutputTraits& traits = Wf->outputTraits();
1818
1819 printHeader(file.f(),lrCellsH,traits);
1820 printLRCells(file.f(),Wf->lrCell(),Wf->kl(),Wf->interface(),traits);
1821
1822 return;
1823 }
1824
lrcwgraphs_f()1825 void lrcwgraphs_f()
1826
1827 /*
1828 This function prints out the W-graphs of the two-sided cells in the group.
1829 It works only for finite groups currently.
1830 */
1831
1832 {
1833 if (!isFiniteType(W)) {
1834 printFile(stderr,"lcells.mess",MESSAGE_DIR);
1835 return;
1836 }
1837
1838 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
1839
1840 OutputFile file;
1841 OutputTraits& traits = Wf->outputTraits();
1842
1843 printHeader(file.f(),lrCellWGraphsH,traits);
1844 printLRCellWGraphs(file.f(),Wf->lrCell(),Wf->kl(),W->interface(),traits);
1845
1846 return;
1847 }
1848
lrwgraph_f()1849 void lrwgraph_f()
1850
1851 /*
1852 Prints out the two-sided wgraph of the current context.
1853 */
1854
1855 {
1856 if (!W->isFullContext() && wgraph_warning) {
1857 printFile(stderr,"wgraph.mess",MESSAGE_DIR);
1858 printf("continue ? y/n\n");
1859 if (!yesNo())
1860 return;
1861 printf("print this message next time ? y/n\n");
1862 if (!yesNo())
1863 wgraph_warning = false;
1864 }
1865
1866 W->fillMu();
1867 if (ERRNO) {
1868 Error(ERRNO);
1869 return;
1870 }
1871
1872 OutputFile file;
1873 OutputTraits& traits = W->outputTraits();
1874
1875 printHeader(file.f(),lrWGraphH,traits);
1876 printLRWGraph(file.f(),W->kl(),W->interface(),traits);
1877
1878 return;
1879 }
1880
lwgraph_f()1881 void lwgraph_f()
1882
1883 /*
1884 Prints out the left wgraph of the current context.
1885 */
1886
1887 {
1888 if (!W->isFullContext() && wgraph_warning) {
1889 printFile(stderr,"wgraph.mess",MESSAGE_DIR);
1890 printf("continue ? y/n\n");
1891 if (!yesNo())
1892 return;
1893 printf("print this message next time ? y/n\n");
1894 if (!yesNo())
1895 wgraph_warning = false;
1896 }
1897
1898 W->fillMu();
1899 if (ERRNO) {
1900 Error(ERRNO);
1901 return;
1902 }
1903
1904 OutputFile file;
1905 OutputTraits& traits = W->outputTraits();
1906
1907 printHeader(file.f(),lWGraphH,traits);
1908 printLWGraph(file.f(),W->kl(),W->interface(),traits);
1909
1910 return;
1911 }
1912
matrix_f()1913 void matrix_f()
1914
1915 /*
1916 Prints the Coxeter matrix.
1917 */
1918
1919 {
1920 interactive::printMatrix(stdout,W);
1921
1922 return;
1923 }
1924
not_implemented_f()1925 void not_implemented_f()
1926
1927 /*
1928 Response for not (yet) implemented commands.
1929 */
1930
1931 {
1932 fprintf(stderr,"Sorry, not implemented yet\n");
1933 return;
1934
1935 }
1936
mu_f()1937 void mu_f()
1938
1939 /*
1940 Response to the mu command. This prints out a single mu-coefficient,
1941 without details.
1942 */
1943
1944 {
1945 static CoxWord g(0);
1946
1947 fprintf(stdout,"first : ");
1948 g = interactive::getCoxWord(W);
1949 CoxNbr x = W->extendContext(g);
1950 if (ERRNO) {
1951 Error(ERRNO);
1952 return;
1953 }
1954
1955 fprintf(stdout,"second : ");
1956 g = interactive::getCoxWord(W);
1957 if (ERRNO) {
1958 Error(ERRNO);
1959 return;
1960 }
1961 CoxNbr y = W->extendContext(g);
1962 if (ERRNO) {
1963 Error(ERRNO);
1964 return;
1965 }
1966
1967 if (!W->inOrder(x,y)) {
1968 fprintf(stderr,"the two elements are not in Bruhat order\n");
1969 return;
1970 }
1971
1972 KLCoeff mu = W->mu(x,y);
1973 if (ERRNO) {
1974 Error(ERRNO,x,y);
1975 return;
1976 }
1977
1978 printf("%lu\n",static_cast<Ulong>(mu));
1979
1980 return;
1981 }
1982
pol_f()1983 void pol_f()
1984
1985 /*
1986 Response to the pol command. This prints out a single polynomial, without
1987 details.
1988 */
1989
1990 {
1991 static CoxWord g(0);
1992
1993 fprintf(stdout,"first : ");
1994 g = interactive::getCoxWord(W);
1995 if (ERRNO) {
1996 Error(ERRNO);
1997 return;
1998 }
1999 CoxNbr x = W->extendContext(g);
2000 if (ERRNO) {
2001 Error(ERRNO);
2002 return;
2003 }
2004
2005 fprintf(stdout,"second : ");
2006 g = interactive::getCoxWord(W);
2007 if (ERRNO) {
2008 Error(ERRNO);
2009 return;
2010 }
2011 CoxNbr y = W->extendContext(g);
2012 if (ERRNO) {
2013 Error(ERRNO);
2014 return;
2015 }
2016
2017 if (!W->inOrder(x,y)) {
2018 fprintf(stderr,"the two elements are not in Bruhat order\n");
2019 return;
2020 }
2021
2022 const kl::KLPol& pol = W->klPol(x,y);
2023 if (ERRNO) {
2024 Error(ERRNO,x,y);
2025 return;
2026 }
2027
2028 print(stdout,pol,"q");
2029 printf("\n");
2030
2031 return;
2032 }
2033
q_f()2034 void q_f()
2035
2036 /*
2037 Exits the current mode. If there is a problem on exit, the exit function
2038 has the option of setting an error, thus preventing the exit.
2039 */
2040
2041 {
2042 CommandTree* tree = treeStack.top();
2043 tree->exit();
2044
2045 if (ERRNO) {
2046 Error(ERRNO);
2047 return;
2048 }
2049
2050 treeStack.pop();
2051
2052 return;
2053 }
2054
qq_f()2055 void qq_f()
2056
2057 /*
2058 Exits the program.
2059 */
2060
2061 {
2062 while(treeStack.size()) {
2063 CommandTree* tree = treeStack.top();
2064 tree->exit();
2065 treeStack.pop();
2066 }
2067
2068 exit(0);
2069 }
2070
rank_f()2071 void rank_f()
2072
2073 /*
2074 Sets the rank.
2075 */
2076
2077 {
2078 CoxGroup* Wloc = interactive::allocCoxGroup(W->type());
2079
2080 if (ERRNO) {
2081 Error(ERRNO);
2082 }
2083 else {
2084 W = Wloc;
2085 }
2086
2087 return;
2088 }
2089
rcorder_f()2090 void rcorder_f()
2091
2092 /*
2093 Prints the right cell order of the current group in a file. Works only for
2094 finite groups.
2095 */
2096
2097 {
2098 if (!isFiniteType(W)) {
2099 printFile(stderr,"rcorder.mess",MESSAGE_DIR);
2100 return;
2101 }
2102
2103 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
2104
2105 Wf->fullContext();
2106 if (ERRNO) {
2107 Error(ERRNO);
2108 return;
2109 }
2110
2111 Wf->fillMu();
2112 if (ERRNO) {
2113 Error(ERRNO);
2114 return;
2115 }
2116
2117 OutputFile file;
2118 OutputTraits& traits = Wf->outputTraits();
2119
2120 printHeader(file.f(),rCOrderH,traits);
2121 printRCOrder(file.f(),Wf->kl(),Wf->interface(),traits);
2122
2123 return;
2124 }
2125
rcells_f()2126 void rcells_f()
2127
2128 /*
2129 This function prints out the right cells in the group, together with the
2130 corresponding W-graphs.
2131 */
2132
2133 {
2134 if (!isFiniteType(W)) {
2135 printFile(stderr,"rcells.mess",MESSAGE_DIR);
2136 return;
2137 }
2138
2139 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
2140
2141 Wf->fullContext();
2142 if (ERRNO) {
2143 Error(ERRNO);
2144 return;
2145 }
2146
2147 Wf->fillMu();
2148 if (ERRNO) {
2149 Error(ERRNO);
2150 return;
2151 }
2152
2153 OutputFile file;
2154 OutputTraits& traits = Wf->outputTraits();
2155
2156 printHeader(file.f(),rCellsH,traits);
2157 printRCells(file.f(),Wf->rCell(),Wf->kl(),Wf->interface(),traits);
2158
2159 return;
2160 }
2161
rcwgraphs_f()2162 void rcwgraphs_f()
2163
2164 /*
2165 This function prints out the W-graphs of the right cells in the group.
2166 It works only for finite groups currently.
2167 */
2168
2169 {
2170 if (!isFiniteType(W)) {
2171 printFile(stderr,"lcells.mess",MESSAGE_DIR);
2172 return;
2173 }
2174
2175 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
2176
2177 OutputFile file;
2178 OutputTraits& traits = Wf->outputTraits();
2179
2180 printHeader(file.f(),rCellWGraphsH,traits);
2181 printRCellWGraphs(file.f(),Wf->rCell(),Wf->kl(),W->interface(),traits);
2182
2183 return;
2184 }
2185
rwgraph_f()2186 void rwgraph_f()
2187
2188 /*
2189 Prints out the right wgraph of the current context.
2190 */
2191
2192 {
2193 if (!W->isFullContext() && wgraph_warning) {
2194 printFile(stderr,"wgraph.mess",MESSAGE_DIR);
2195 printf("continue ? y/n\n");
2196 if (!yesNo())
2197 return;
2198 printf("print this message next time ? y/n\n");
2199 if (!yesNo())
2200 wgraph_warning = false;
2201 }
2202
2203 W->fillMu();
2204 if (ERRNO) {
2205 Error(ERRNO);
2206 return;
2207 }
2208
2209 OutputFile file;
2210 OutputTraits& traits = W->outputTraits();
2211
2212 printHeader(file.f(),rWGraphH,traits);
2213 printRWGraph(file.f(),W->kl(),W->interface(),traits);
2214
2215 return;
2216 }
2217
schubert_f()2218 void schubert_f()
2219
2220 /*
2221 Response to the schubert command. This will print out the information
2222 corresponding to one element in the k-l basis, and the information on
2223 the singularities of the corresponding Schubert variety, in the format
2224 popularized by Goresky.
2225 */
2226
2227 {
2228 static CoxWord g(0);
2229
2230 printf("Enter your element (finish with a carriage-return) :\n");
2231 g = interactive::getCoxWord(W);
2232 if (ERRNO) {
2233 Error(ERRNO);
2234 return;
2235 }
2236
2237 CoxNbr y = W->extendContext(g);
2238 if (ERRNO) {
2239 Error(ERRNO);
2240 return;
2241 }
2242
2243 interactive::OutputFile file;
2244 OutputTraits& traits = W->outputTraits();
2245
2246 printHeader(file.f(),closureH,traits);
2247 printClosure(file.f(),y,W->kl(),W->interface(),traits);
2248
2249 return;
2250 }
2251
show_f()2252 void show_f()
2253
2254 /*
2255 Response to the show command. This maps out the computation of a Kazhdan-
2256 Lusztig polynomial, letting you choose the descent generator.
2257
2258 If no generator is given, the default descent generator is used.
2259 */
2260
2261 {
2262 static CoxWord g(0);
2263
2264 fprintf(stdout,"first : ");
2265 g = interactive::getCoxWord(W);
2266 if (ERRNO) {
2267 Error(ERRNO);
2268 return;
2269 }
2270 CoxNbr x = W->extendContext(g);
2271 if (ERRNO) {
2272 Error(ERRNO);
2273 return;
2274 }
2275
2276 fprintf(stdout,"second : ");
2277 g = interactive::getCoxWord(W);
2278 if (ERRNO) {
2279 Error(ERRNO);
2280 return;
2281 }
2282 CoxNbr y = W->extendContext(g);
2283 if (ERRNO) {
2284 Error(ERRNO);
2285 return;
2286 }
2287
2288 if (!W->inOrder(x,y)) {
2289 fprintf(stderr,"the two elements are not in Bruhat order\n");
2290 return;
2291 }
2292
2293 fprintf(stdout,"generator (carriage return for default) : ");
2294 LFlags f = W->descent(y);
2295 Generator s = interactive::getGenerator(W,f);
2296 if (ERRNO) {
2297 Error (ERRNO);
2298 return;
2299 }
2300
2301 interactive::OutputFile file;
2302 showKLPol(file.f(),W->kl(),x,y,W->interface(),s);
2303
2304 return;
2305 }
2306
showmu_f()2307 void showmu_f()
2308
2309 /*
2310 Response to the showmu command. This maps out the computation of a
2311 mu-coefficient, letting you choose the descent generator.
2312
2313 If no generator is given, the default descent generator is used.
2314 */
2315
2316 {
2317 static CoxWord g(0);
2318
2319 fprintf(stdout,"first : ");
2320 g = interactive::getCoxWord(W);
2321 if (ERRNO) {
2322 Error(ERRNO);
2323 return;
2324 }
2325 CoxNbr x = W->extendContext(g);
2326 if (ERRNO) {
2327 Error(ERRNO);
2328 return;
2329 }
2330
2331 fprintf(stdout,"second : ");
2332 g = interactive::getCoxWord(W);
2333 if (ERRNO) {
2334 Error(ERRNO);
2335 return;
2336 }
2337 CoxNbr y = W->extendContext(g);
2338 if (ERRNO) {
2339 Error(ERRNO);
2340 return;
2341 }
2342
2343 if (!W->inOrder(x,y)) {
2344 fprintf(stderr,"the two elements are not in Bruhat order\n");
2345 return;
2346 }
2347
2348 interactive::OutputFile file;
2349 showMu(file.f(),W->kl(),x,y,W->interface());
2350
2351 return;
2352 }
2353
slocus_f()2354 void slocus_f ()
2355
2356 /*
2357 Response to the slocus command. Prints out the singular locus of the
2358 Schubert variety cl(X_y).
2359 */
2360
2361 {
2362 static CoxWord g(0);
2363
2364 printf("Enter your element (finish with a carriage-return) :\n");
2365
2366 g = interactive::getCoxWord(W);
2367 if (ERRNO) {
2368 Error(ERRNO);
2369 return;
2370 }
2371 CoxNbr y = W->extendContext(g);
2372 if (ERRNO) {
2373 Error(ERRNO);
2374 return;
2375 }
2376
2377 OutputFile file;
2378 OutputTraits& traits = W->outputTraits();
2379
2380 printHeader(file.f(),slocusH,traits);
2381 printSingularLocus(file.f(),y,W->kl(),W->interface(),traits);
2382
2383 return;
2384 }
2385
sstratification_f()2386 void sstratification_f ()
2387
2388 /*
2389 Response to the slocus command. Prints out the singular locus of the
2390 Schubert variety cl(X_y).
2391 */
2392
2393 {
2394 static CoxWord g(0);
2395
2396 printf("Enter your element (finish with a carriage-return) :\n");
2397
2398 g = interactive::getCoxWord(W);
2399 if (ERRNO) {
2400 Error(ERRNO);
2401 return;
2402 }
2403 CoxNbr y = W->extendContext(g);
2404 if (ERRNO) {
2405 Error(ERRNO);
2406 return;
2407 }
2408
2409 OutputFile file;
2410 OutputTraits& traits = W->outputTraits();
2411
2412 printHeader(file.f(),sstratificationH,traits);
2413 printSingularStratification(file.f(),y,W->kl(),W->interface(),traits);
2414
2415 return;
2416 }
2417
type_f()2418 void type_f()
2419
2420 /*
2421 This function sets the type of W, i.e., gets a type and rank from the
2422 user and sets W to a new group of that type and rank.
2423 */
2424
2425 {
2426 CoxGroup* Wloc = interactive::allocCoxGroup();
2427
2428 if (ERRNO) {
2429 Error(ERRNO);
2430 }
2431 else {
2432 delete W;
2433 wgraph_warning = true;
2434 W = Wloc;
2435 }
2436
2437 return;
2438 }
2439
uneq_f()2440 void uneq_f()
2441
2442 /*
2443 Response to the uneq command.
2444 */
2445
2446 {
2447 activate(uneqCommandTree());
2448 return;
2449 }
2450
2451 namespace uneq {
2452
klbasis_f()2453 void klbasis_f()
2454
2455 /*
2456 Prints out one element in the k-l basis of the group, in the format
2457 defined by the current output mode.
2458 */
2459
2460 {
2461 CoxWord g(0);
2462
2463 printf("enter your element (finish with a carriage return) :\n");
2464 g = interactive::getCoxWord(W);
2465 if (ERRNO) {
2466 Error(ERRNO);
2467 return;
2468 }
2469
2470 CoxNbr y = W->extendContext(g);
2471 if (ERRNO) {
2472 Error(ERRNO);
2473 return;
2474 }
2475
2476 uneqkl::HeckeElt h(0);
2477
2478 W->uneqcBasis(h,y);
2479 if (ERRNO) {
2480 Error(ERRNO);
2481 return;
2482 }
2483
2484 interactive::OutputFile file;
2485 OutputTraits& traits = W->outputTraits();
2486
2487 printHeader(file.f(),basisH,traits);
2488 printAsBasisElt(file.f(),h,W->schubert(),W->interface(),traits);
2489
2490 return;
2491 }
2492
lcells_f()2493 void lcells_f()
2494
2495 /*
2496 This function prints out the left cells in the group.
2497 */
2498
2499 {
2500 if (!isFiniteType(W)) {
2501 printFile(stderr,"lcells.mess",MESSAGE_DIR);
2502 return;
2503 }
2504
2505 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
2506
2507 Wf->fullContext();
2508 if (ERRNO) {
2509 Error(ERRNO);
2510 return;
2511 }
2512
2513 Wf->fillUEMu();
2514 if (ERRNO) {
2515 Error(ERRNO);
2516 return;
2517 }
2518
2519 OutputFile file;
2520 OutputTraits& traits = Wf->outputTraits();
2521
2522 printHeader(file.f(),lCellsH,traits);
2523 printLCells(file.f(),Wf->lUneqCell(),Wf->uneqkl(),Wf->interface(),traits);
2524
2525 return;
2526 }
2527
lcorder_f()2528 void lcorder_f()
2529
2530 /*
2531 Prints the left cell order of the closure of the current group in a file.
2532 Works only for finite groups.
2533 */
2534
2535 {
2536 if (!isFiniteType(W)) {
2537 printFile(stderr,"lcorder.mess",MESSAGE_DIR);
2538 return;
2539 }
2540
2541 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
2542
2543 Wf->fullContext();
2544 if (ERRNO) {
2545 Error(ERRNO);
2546 return;
2547 }
2548
2549 Wf->fillUEMu();
2550 if (ERRNO) {
2551 Error(ERRNO);
2552 return;
2553 }
2554
2555 OutputFile file;
2556 OutputTraits& traits = Wf->outputTraits();
2557
2558 printHeader(file.f(),lCOrderH,traits);
2559 printLCOrder(file.f(),Wf->uneqkl(),Wf->interface(),traits);
2560
2561 return;
2562 }
2563
lrcorder_f()2564 void lrcorder_f()
2565
2566 /*
2567 Prints the two-sided cell order of the closure of the current group in a
2568 file. Works only for finite groups.
2569 */
2570
2571 {
2572 if (!isFiniteType(W)) {
2573 printFile(stderr,"uneq/lrcorder.mess",MESSAGE_DIR);
2574 return;
2575 }
2576
2577 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
2578
2579 Wf->fullContext();
2580 if (ERRNO) {
2581 Error(ERRNO);
2582 return;
2583 }
2584
2585 Wf->fillUEMu();
2586 if (ERRNO) {
2587 Error(ERRNO);
2588 return;
2589 }
2590
2591 OutputFile file;
2592 OutputTraits& traits = Wf->outputTraits();
2593
2594 printHeader(file.f(),lrCOrderH,traits);
2595 printLRCOrder(file.f(),Wf->uneqkl(),Wf->interface(),traits);
2596
2597 return;
2598 }
2599
lrcells_f()2600 void lrcells_f()
2601
2602 /*
2603 This function prints out the two-sided cells in the group. Works only for
2604 finite groups.
2605 */
2606
2607 {
2608 if (!isFiniteType(W)) {
2609 printFile(stderr,"uneq/lrcells.mess",MESSAGE_DIR);
2610 return;
2611 }
2612
2613 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
2614
2615 Wf->fullContext();
2616 if (ERRNO) {
2617 Error(ERRNO);
2618 return;
2619 }
2620
2621 Wf->fillUEMu();
2622 if (ERRNO) {
2623 Error(ERRNO);
2624 return;
2625 }
2626
2627 OutputFile file;
2628 OutputTraits& traits = Wf->outputTraits();
2629
2630 printHeader(file.f(),lrCellsH,traits);
2631 printLRCells(file.f(),Wf->lrUneqCell(),Wf->uneqkl(),Wf->interface(),traits);
2632
2633 return;
2634 }
2635
mu_f()2636 void mu_f()
2637
2638 /*
2639 Response to the "mu" command. Prints out a single mu-coefficient. When
2640 the generator s act on the left, we use the fact that mu(left_s,x,y) is
2641 equal to mu(right_s,x^{-1},y^{-1}) to go over to the right action. This
2642 is necessary because the mu-tables are kept only for right actions.
2643 */
2644
2645 {
2646 static CoxWord g(0);
2647 bool leftAction = false;
2648
2649 fprintf(stdout,"generator : ");
2650 Generator s = getGenerator(W);
2651
2652 if (s >= W->rank()) { // action is on the left
2653 s -= W->rank();
2654 leftAction = true;
2655 }
2656
2657 fprintf(stdout,"first : ");
2658 g = interactive::getCoxWord(W);
2659 if (leftAction)
2660 W->inverse(g);
2661 if (!W->isDescent(g,s)) { // mu(s,x,y) is undefined
2662 fprintf(stderr,"xs is greater than x\n");
2663 return;
2664 }
2665 CoxNbr x = W->extendContext(g);
2666 if (ERRNO) {
2667 Error(ERRNO);
2668 return;
2669 }
2670
2671 fprintf(stdout,"second : ");
2672 g = interactive::getCoxWord(W);
2673 if (leftAction)
2674 W->inverse(g);
2675 if (W->isDescent(g,s)) { // mu(s,x,y) is undefined
2676 fprintf(stderr,"ys is smaller than y\n");
2677 return;
2678 }
2679 if (ERRNO) {
2680 Error(ERRNO);
2681 return;
2682 }
2683 CoxNbr y = W->extendContext(g);
2684 if (ERRNO) {
2685 Error(ERRNO);
2686 return;
2687 }
2688
2689 if (x == y) {
2690 fprintf(stderr,"the two elements are equal\n");
2691 return;
2692 }
2693
2694 if (!W->inOrder(x,y)) {
2695 fprintf(stderr,"the two elements are not in Bruhat order\n");
2696 return;
2697 }
2698
2699 const uneqkl::MuPol& mu = W->uneqmu(s,x,y);
2700 if (ERRNO) {
2701 Error(ERRNO,x,y);
2702 return;
2703 }
2704
2705 print(stdout,mu,"v");
2706 printf("\n");
2707
2708 return;
2709 }
2710
pol_f()2711 void pol_f()
2712
2713 /*
2714 Response to the "pol" command. Prints out a single polynomial.
2715 */
2716
2717 {
2718 static CoxWord g(0);
2719
2720 fprintf(stdout,"first : ");
2721 g = interactive::getCoxWord(W);
2722 if (ERRNO) {
2723 Error(ERRNO);
2724 return;
2725 }
2726 CoxNbr x = W->extendContext(g);
2727 if (ERRNO) {
2728 Error(ERRNO);
2729 return;
2730 }
2731
2732 fprintf(stdout,"second : ");
2733 g = interactive::getCoxWord(W);
2734 if (ERRNO) {
2735 Error(ERRNO);
2736 return;
2737 }
2738 CoxNbr y = W->extendContext(g);
2739 if (ERRNO) {
2740 Error(ERRNO);
2741 return;
2742 }
2743
2744 if (!W->inOrder(x,y)) {
2745 fprintf(stderr,"the two elements are not in Bruhat order\n");
2746 return;
2747 }
2748
2749 const uneqkl::KLPol& pol = W->uneqklPol(x,y);
2750 if (ERRNO) {
2751 Error(ERRNO,x,y);
2752 return;
2753 }
2754
2755 print(stdout,pol,"q");
2756 printf("\n");
2757
2758 return;
2759 }
2760
rcells_f()2761 void rcells_f()
2762
2763 /*
2764 This function prints out the left cells in the group. Works only for finite
2765 groups.
2766 */
2767
2768 {
2769 if (!isFiniteType(W)) {
2770 printFile(stderr,"rcells.mess",MESSAGE_DIR);
2771 return;
2772 }
2773
2774 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
2775
2776 Wf->fullContext();
2777 if (ERRNO) {
2778 Error(ERRNO);
2779 return;
2780 }
2781
2782 Wf->fillUEMu();
2783 if (ERRNO) {
2784 Error(ERRNO);
2785 return;
2786 }
2787
2788 OutputFile file;
2789 OutputTraits& traits = Wf->outputTraits();
2790
2791 printHeader(file.f(),rCellsH,traits);
2792 printRCells(file.f(),Wf->rUneqCell(),Wf->uneqkl(),Wf->interface(),traits);
2793
2794 return;
2795 }
2796
rcorder_f()2797 void rcorder_f()
2798
2799 /*
2800 Prints the right cell order of the current group in a file. Works only for
2801 finite groups.
2802 */
2803
2804 {
2805 if (!isFiniteType(W)) {
2806 printFile(stderr,"rcorder.mess",MESSAGE_DIR);
2807 return;
2808 }
2809
2810 FiniteCoxGroup* Wf = dynamic_cast<FiniteCoxGroup*> (W);
2811
2812 Wf->fullContext();
2813 if (ERRNO) {
2814 Error(ERRNO);
2815 return;
2816 }
2817
2818 Wf->fillUEMu();
2819 if (ERRNO) {
2820 Error(ERRNO);
2821 return;
2822 }
2823
2824 OutputFile file;
2825 OutputTraits& traits = Wf->outputTraits();
2826
2827 printHeader(file.f(),rCOrderH,traits);
2828 printRCOrder(file.f(),Wf->uneqkl(),Wf->interface(),traits);
2829
2830 return;
2831 }
2832
2833 };
2834
2835 };
2836
2837 namespace commands {
2838
abort_f()2839 void interface::abort_f()
2840
2841 /*
2842 Aborts the interface modification. Bypasses the exit function,
2843 so that there is no further checking of the abandoned choices.
2844 */
2845
2846 {
2847 delete in_buf;
2848 in_buf = 0;
2849 treeStack.pop();
2850
2851 return;
2852 }
2853
alphabetic_f()2854 void interface::alphabetic_f()
2855
2856 /*
2857 Sets i/o to the standard alphabetic conventions : the symbols are the
2858 alphabetic sequence, prefix and postfix are empty, and the separator is
2859 "." iff the rank is > 26.
2860 */
2861
2862 {
2863 delete in_buf;
2864 in_buf = new GroupEltInterface(W->rank(),Alphabetic());
2865 W->interface().setIn(*in_buf);
2866 W->interface().setOut(*in_buf);
2867
2868 return;
2869 }
2870
bourbaki_f()2871 void interface::bourbaki_f()
2872
2873 /*
2874 Sets Bourbaki conventions. This means that the ordering is reverted in
2875 types B and D, and symbols as well.
2876
2877 NOTE : currently not implemented for affine groups.
2878 */
2879
2880 {
2881 delete in_buf;
2882 in_buf = new GroupEltInterface(W->interface().inInterface());
2883 in::bourbaki_f();
2884 W->interface().setIn(*in_buf);
2885
2886 delete in_buf;
2887 in_buf = new GroupEltInterface(W->interface().outInterface());
2888 out::bourbaki_f();
2889 W->interface().setOut(*in_buf);
2890
2891 return;
2892 }
2893
decimal_f()2894 void interface::decimal_f()
2895
2896 /*
2897 Sets i/o to the standard decimal conventions : the symbols are the
2898 decimal sequence, prefix and postfix are empty, and the separator is
2899 "." iff the rank is > 9.
2900 */
2901
2902 {
2903 delete in_buf;
2904 in_buf = new GroupEltInterface(W->rank(),Decimal());
2905 W->interface().setIn(*in_buf);
2906 W->interface().setOut(*in_buf);
2907
2908 return;
2909 }
2910
default_f()2911 void interface::default_f()
2912
2913 /*
2914 Sets i/o settings to the default style. This means that we use decimal
2915 symbols, no prefix or postfix, and separator "." only when rank is >= 10.
2916 The ordering is the internal default ordering.
2917 */
2918
2919 {
2920 delete in_buf;
2921 in_buf = new GroupEltInterface(W->rank());
2922
2923 W->interface().setIn(*in_buf);
2924 W->interface().setOut(*in_buf);
2925
2926 W->interface().setOrder(identityOrder(W->rank()));
2927 W->interface().setDescent(Default());
2928 W->setOutputTraits(Pretty());
2929
2930 return;
2931 }
2932
gap_f()2933 void interface::gap_f()
2934
2935 /*
2936 Sets i/o settings to GAP style. This means first of all that Bourbaki
2937 conventions are adopted; decimal symbols are used for i/o with prefix
2938 "[", separator "," and postfix "]". Furthermore, output to files is
2939 done in GAP style, which produces files that are directly legible by
2940 GAP3.
2941 */
2942
2943 {
2944 delete in_buf;
2945 in_buf = new GroupEltInterface(W->rank(),GAP());
2946
2947 in::bourbaki_f();
2948 W->interface().setIn(*in_buf);
2949
2950 out::bourbaki_f();
2951 W->interface().setOut(*in_buf);
2952 W->interface().setDescent(GAP());
2953 W->setOutputTraits(GAP());
2954
2955 return;
2956 }
2957
hexadecimal_f()2958 void interface::hexadecimal_f()
2959
2960 /*
2961 Sets i/o to the standard hexadecimal conventions : the symbols are the
2962 hexadecimal sequence, prefix and postfix are empty, and the separator is
2963 "." iff the rank is > 15.
2964 */
2965
2966 {
2967 delete in_buf;
2968 in_buf = new GroupEltInterface(W->rank(),Hexadecimal());
2969 W->interface().setIn(*in_buf);
2970
2971 W->interface().setOut(*in_buf);
2972
2973 return;
2974 }
2975
in_f()2976 void interface::in_f()
2977
2978 {
2979 activate(inCommandTree());
2980 return;
2981 }
2982
ordering_f()2983 void interface::ordering_f()
2984
2985 /*
2986 Allows the user to change the generator ordering.
2987 */
2988
2989 {
2990 static Permutation in_order(W->rank());
2991
2992 changeOrdering(W,in_order);
2993
2994 if (ERRNO) {
2995 Error(ERRNO);
2996 return;
2997 }
2998
2999 W->setOrdering(in_order);
3000
3001 return;
3002 }
3003
out_f()3004 void interface::out_f()
3005
3006 {
3007 activate(outCommandTree());
3008 return;
3009 }
3010
permutation_f()3011 void interface::permutation_f()
3012
3013 /*
3014 Activates permutation i/o.
3015 */
3016
3017 {
3018 using namespace coxeter;
3019
3020 if (!isTypeA(W->type())) {
3021 printFile(stderr,"permutation.mess",MESSAGE_DIR);
3022 return;
3023 }
3024
3025 TypeACoxGroup* WA = dynamic_cast<TypeACoxGroup*>(W);
3026
3027 WA->setPermutationInput(true);
3028 WA->setPermutationOutput(true);
3029
3030 W->interface().setOrder(identityOrder(W->rank()));
3031 W->interface().setDescent(Default());
3032 W->setOutputTraits(Pretty());
3033
3034 return;
3035 }
3036
symbol_f()3037 void interface::symbol_f()
3038
3039 /*
3040 Resets a symbol in in_buf (this will become either an input or an output
3041 symbol).
3042 */
3043
3044 {
3045 static String buf(0);
3046
3047 const Interface& I = W->interface();
3048 Generator s = undef_generator;
3049 reset(buf);
3050
3051 do {
3052 if (ERRNO)
3053 Error(ERRNO);
3054 printf("enter the generator symbol you wish to change, ? to abort:\n");
3055 getInput(stdin,buf,0);
3056 if (buf[0] == '?')
3057 return;
3058 io::skipSpaces(buf,0);
3059 Token tok;
3060 I.symbolTree().find(buf,0,tok);
3061 if (tokenType(tok) != generator_type)/* error */
3062 ERRNO = NOT_GENERATOR;
3063 else
3064 s = tok-1;
3065 } while (ERRNO);
3066
3067 printf("enter the new symbol (finish with a carriage return):\n");
3068 getInput(stdin,buf,0);
3069 in_buf->setSymbol(s,buf);
3070
3071 return;
3072 }
3073
terse_f()3074 void interface::terse_f()
3075
3076 /*
3077 Sets i/o settings to terse style. This style is meant for outputting files
3078 that are easily parsed by computer. Th ordering of the generators is left
3079 untouched, and can be set independently by the user. Decimal output symbols
3080 are chosen, prefix is set to "[", postfix to "]" and separator to ",".
3081 */
3082
3083 {
3084 delete in_buf;
3085 in_buf = new GroupEltInterface(W->rank(),GAP());
3086 W->interface().setIn(*in_buf);
3087 W->interface().setOut(*in_buf);
3088
3089 W->interface().setDescent(Default());
3090 W->setOutputTraits(Terse());
3091
3092 return;
3093 }
3094
alphabetic_f()3095 void interface::in::alphabetic_f()
3096
3097 /*
3098 Sets the input symbols to the alphabetic sequence.
3099 */
3100
3101 {
3102 const String* alpha = alphabeticSymbols(in_buf->symbol.size());
3103
3104 for (Ulong j = 0; j < in_buf->symbol.size(); ++j) {
3105 in_buf->symbol[j] = alpha[j];
3106 }
3107
3108 return;
3109 }
3110
bourbaki_f()3111 void interface::in::bourbaki_f()
3112
3113 /*
3114 Sets Bourbaki conventions for input. This means reverting the ordering
3115 of the input symbols in types B and D.
3116 */
3117
3118 {
3119 const Type& x = W->type();
3120
3121 if (!isFiniteType(x))
3122 return;
3123 if (!(isTypeB(x) || isTypeD(x)))
3124 return;
3125
3126 for (Generator s = 0; s < W->rank(); ++s) {
3127 in_buf->symbol[s] = W->interface().inSymbol(W->rank()-s-1);
3128 }
3129
3130 return;
3131 }
3132
decimal_f()3133 void interface::in::decimal_f()
3134
3135 /*
3136 Sets the input symbols to the decimal sequence.
3137 */
3138
3139 {
3140 const String* dec = decimalSymbols(in_buf->symbol.size());
3141
3142 for (Ulong j = 0; j < in_buf->symbol.size(); ++j) {
3143 in_buf->symbol[j] = dec[j];
3144 }
3145
3146 return;
3147 }
3148
default_f()3149 void interface::in::default_f()
3150
3151 /*
3152 Sets the input interface to the default style.
3153 */
3154
3155 {
3156 delete in_buf;
3157 in_buf = new GroupEltInterface(W->rank());
3158
3159 return;
3160 }
3161
gap_f()3162 void interface::in::gap_f()
3163
3164 /*
3165 Sets the input interface to GAP style, and enforces Bourbaki conventions.
3166 */
3167
3168 {
3169 delete in_buf;
3170 in_buf = new GroupEltInterface(W->rank(),GAP());
3171 in::bourbaki_f();
3172
3173 return;
3174 }
3175
hexadecimal_f()3176 void interface::in::hexadecimal_f()
3177
3178 /*
3179 Sets the input symbols to the hexadecimal sequence.
3180 */
3181
3182 {
3183 const String* hex = hexSymbols(in_buf->symbol.size());
3184
3185 for (Ulong j = 0; j < in_buf->symbol.size(); ++j) {
3186 in_buf->symbol[j] = hex[j];
3187 }
3188
3189 return;
3190 }
3191
permutation_f()3192 void interface::in::permutation_f()
3193
3194 /*
3195 Sets input to permutation mode (type A only.)
3196 */
3197
3198 {
3199 using namespace coxeter;
3200
3201 if (!isTypeA(W->type())) {
3202 printFile(stderr,"permutation.mess",MESSAGE_DIR);
3203 return;
3204 }
3205
3206 TypeACoxGroup* WA = dynamic_cast<TypeACoxGroup*>(W);
3207 WA->setPermutationInput(true);
3208
3209 delete in_buf;
3210 in_buf = 0;
3211
3212 return;
3213 }
3214
postfix_f()3215 void interface::in::postfix_f()
3216
3217 /*
3218 Resets the input postfix.
3219 */
3220
3221 {
3222 printf("Enter the new input postfix (finish with a carriage return):\n");
3223 String buf(0);
3224 getInput(stdin,buf,0);
3225 in_buf->setPostfix(buf);
3226 return;
3227 }
3228
prefix_f()3229 void interface::in::prefix_f()
3230
3231 /*
3232 Resets the input prefix.
3233 */
3234
3235 {
3236 printf("Enter the new input prefix (finish with a carriage return):\n");
3237 String buf(0);
3238 getInput(stdin,buf,0);
3239 in_buf->setPrefix(buf);
3240 return;
3241 }
3242
separator_f()3243 void interface::in::separator_f()
3244
3245 /*
3246 Resets the input separator.
3247 */
3248
3249 {
3250 printf("Enter the new input separator (finish with a carriage return):\n");
3251 String buf(0);
3252 getInput(stdin,buf,0);
3253 in_buf->setSeparator(buf);
3254 return;
3255 }
3256
terse_f()3257 void interface::in::terse_f()
3258
3259 /*
3260 Sets the input interface to terse style (the same as GAP style).
3261 */
3262
3263 {
3264 delete in_buf;
3265 in_buf = new GroupEltInterface(W->rank(),GAP());
3266
3267 return;
3268 }
3269
alphabetic_f()3270 void interface::out::alphabetic_f()
3271
3272 /*
3273 Changes the output symbols to hexadecimal.
3274 */
3275
3276 {
3277 const String* alpha = alphabeticSymbols(in_buf->symbol.size());
3278
3279 for (Ulong j = 0; j < in_buf->symbol.size(); ++j) {
3280 in_buf->symbol[j] = alpha[j];
3281 }
3282
3283 return;
3284 }
3285
bourbaki_f()3286 void interface::out::bourbaki_f()
3287
3288 /*
3289 Sets Bourbaki conventions for input. This means reverting the ordering
3290 of the output symbols in types B and D, and setting the output ordering
3291 to the reverse of the default one.
3292 */
3293
3294 {
3295 const Type& x = W->type();
3296
3297 if (!isFiniteType(x))
3298 return;
3299 if (!(isTypeB(x) || isTypeD(x))) {
3300 W->setOrdering(identityOrder(W->rank()));
3301 return;
3302 }
3303
3304 for (Generator s = 0; s < W->rank(); ++s) {
3305 in_buf->symbol[s] = W->interface().outSymbol(W->rank()-s-1);
3306 }
3307
3308 Permutation a(W->rank());
3309
3310 for (Generator s = 0; s < W->rank(); ++s) {
3311 a[s] = W->rank()-1-s;
3312 }
3313
3314 W->setOrdering(a);
3315
3316 return;
3317 }
3318
decimal_f()3319 void interface::out::decimal_f()
3320
3321 /*
3322 Changes the output symbols to decimal.
3323 */
3324
3325 {
3326 const String* dec = decimalSymbols(in_buf->symbol.size());
3327
3328 for (Ulong j = 0; j < in_buf->symbol.size(); ++j) {
3329 in_buf->symbol[j] = dec[j];
3330 }
3331
3332 return;
3333 }
3334
default_f()3335 void interface::out::default_f()
3336
3337 /*
3338 Sets output styles to the default style.
3339 */
3340
3341 {
3342 delete in_buf;
3343 in_buf = new GroupEltInterface(W->rank());
3344 W->setOrdering(identityOrder(W->rank()));
3345
3346 W->setOutputTraits(Pretty());
3347
3348 return;
3349 }
3350
gap_f()3351 void interface::out::gap_f()
3352
3353 /*
3354 Sets output styles to GAP style, and enforces Bourbaki conventions.
3355 */
3356
3357 {
3358 delete in_buf;
3359 in_buf = new GroupEltInterface(W->rank(),GAP());
3360 W->setOrdering(identityOrder(W->rank()));
3361 out::bourbaki_f();
3362
3363 W->interface().setDescent(GAP());
3364 W->interface().setOut(*in_buf); // has to be done here so that output traits
3365 // will be correct.
3366 W->setOutputTraits(GAP());
3367
3368 return;
3369 }
3370
hexadecimal_f()3371 void interface::out::hexadecimal_f()
3372
3373 /*
3374 Changes the output symbols to hexadecimal.
3375 */
3376
3377 {
3378 const String* hex = hexSymbols(in_buf->symbol.size());
3379
3380 for (Ulong j = 0; j < in_buf->symbol.size(); ++j) {
3381 in_buf->symbol[j] = hex[j];
3382 }
3383
3384 return;
3385 }
3386
permutation_f()3387 void interface::out::permutation_f()
3388
3389 /*
3390 Sets output to permutation mode (type A only.)
3391 */
3392
3393 {
3394 using namespace coxeter;
3395
3396 if (!isTypeA(W->type())) {
3397 printFile(stderr,"permutation.mess",MESSAGE_DIR);
3398 return;
3399 }
3400
3401 TypeACoxGroup* WA = dynamic_cast<TypeACoxGroup*>(W);
3402
3403 WA->setPermutationOutput(true);
3404
3405 W->interface().setOrder(identityOrder(W->rank()));
3406 W->interface().setDescent(Default());
3407 W->setOutputTraits(Pretty());
3408
3409 delete in_buf;
3410 in_buf = 0;
3411
3412 return;
3413 }
3414
postfix_f()3415 void interface::out::postfix_f()
3416
3417 /*
3418 Resets the output postfix.
3419 */
3420
3421 {
3422 printf("enter the new output postfix (finish with a carriage return):\n");
3423 String buf(0);
3424 getInput(stdin,buf,0);
3425 in_buf->setPostfix(buf);
3426 return;
3427 }
3428
prefix_f()3429 void interface::out::prefix_f()
3430
3431 /*
3432 Resets the output prefix.
3433 */
3434
3435 {
3436 printf("Enter the new output prefix (finish with a carriage return):\n");
3437 String buf(0);
3438 getInput(stdin,buf,0);
3439 in_buf->setPrefix(buf);
3440 return;
3441 }
3442
separator_f()3443 void interface::out::separator_f()
3444
3445 /*
3446 Resets the output separator.
3447 */
3448
3449 {
3450 printf("Enter the new output separator (finish with a carriage return):\n");
3451 String buf(0);
3452 getInput(stdin,buf,0);
3453 in_buf->setSeparator(buf);
3454 return;
3455 }
3456
terse_f()3457 void interface::out::terse_f()
3458
3459 /*
3460 Sets output styles to terse style (the same as GAP style).
3461 */
3462
3463 {
3464 delete in_buf;
3465 in_buf = new GroupEltInterface(W->rank(),GAP());
3466
3467 W->interface().setDescent(Default());
3468 W->interface().setOut(*in_buf); // has to be done here so that output
3469 // traits will be correct
3470 W->setOutputTraits(Terse());
3471
3472 return;
3473 }
3474
3475 };
3476
3477 /*****************************************************************************
3478
3479 Chapter VI -- Miscellaneous.
3480
3481 This section contains some auxiliary functions :
3482
3483 - printCommands(file,tree) : prints info about the various commands
3484 on the tree;
3485 - printCommandTree(file,cell) : the recursive function doing the actual
3486 work;
3487 - interface_entry() : entry function for the interface mode;
3488 - interface_exit() : exit function for the interface mode;
3489 - interface::in_entry() : entry function for the interface::in mode;
3490 - interface::in_exit() : exit function for the interface::in mode;
3491 - interface::out_entry() : entry function for the interface::out mode;
3492 - interface::out_exit() : exit function for the interface::out mode;
3493 - main_entry() : entry function for the main mode;
3494 - main_exit() : exit function for the main mode;
3495 - uneq_entry() : entry function for the uneq mode;
3496 - uneq_exit() : exit function for the uneq mode;
3497
3498 *****************************************************************************/
3499
3500 namespace commands {
3501
printCommands(FILE * file,CommandTree * tree)3502 void printCommands(FILE* file, CommandTree* tree)
3503
3504 /*
3505 Prints one line for each command on the tree (sorted in alphabetical order)
3506 with the name of the command and the information contained in the tag field.
3507 */
3508
3509 {
3510 printCommandTree(file,tree->root()->left);
3511 return;
3512 }
3513
3514 };
3515
currentGroup()3516 CoxGroup* commands::currentGroup()
3517
3518 /*
3519 Returns the "current" Coxeter group.
3520
3521 NOTE : this will probably have to be refined in the future.
3522 */
3523
3524 {
3525 return W;
3526 }
3527
3528 namespace {
3529
printCommandTree(FILE * file,DictCell<CommandData> * cell)3530 void printCommandTree(FILE* file, DictCell<CommandData>* cell)
3531
3532 {
3533 if (cell == 0)
3534 return;
3535
3536 if (cell->fullname) { /* print command info */
3537 CommandData* cd = cell->value();
3538 fprintf(file," - %s : %s;\n",cd->name.ptr(),cd->tag.ptr());
3539 };
3540
3541 printCommandTree(file,cell->left);
3542 printCommandTree(file,cell->right);
3543
3544 return;
3545 }
3546
interface_entry()3547 void interface_entry()
3548
3549 {
3550 commands::interface::in_buf = new GroupEltInterface(W->rank());
3551 return;
3552 }
3553
interface_exit()3554 void interface_exit()
3555
3556 {
3557 delete commands::interface::in_buf;
3558 commands::interface::in_buf = 0;
3559 return;
3560 }
3561
main_entry()3562 void main_entry()
3563
3564 /*
3565 Sets the type and rank. This is used as entry function for the main mode,
3566 and as the function that restarts the program when we change the type.
3567
3568 NOTE : error handling should be done by the calling function.
3569
3570 NOTE : something should be done about deallocating before reallocating!
3571 */
3572
3573 {
3574 W = interactive::allocCoxGroup();
3575
3576 /* an error may be set here */
3577
3578 return;
3579 }
3580
3581 };
3582
3583 namespace commands {
3584
in_entry()3585 void interface::in_entry()
3586
3587 /*
3588 Entry function to the input interface modification mode. The global variable
3589 in_buf is originally set to value for the current group.
3590 */
3591
3592 {
3593 Permutation a(W->interface().order());
3594 a.inverse();
3595
3596 printf("current input symbols are the following :\n\n");
3597 printInterface(stdout,W->interface().inInterface(),a);
3598 printf("\n");
3599
3600 in_buf = new GroupEltInterface(W->interface().inInterface());
3601
3602 return;
3603 }
3604
in_exit()3605 void interface::in_exit()
3606
3607 /*
3608 Exit function from the input modification mode. It checks if the
3609 modifications made by the user are consistent with the ones that will
3610 remain from the old interface; if yes, it confirms the modifications
3611 and exits peacefully; if not, it prints out the problems and keeps
3612 the user in the mode.
3613 */
3614
3615 {
3616 if (in_buf == 0) // hack to prevent execution in special cases
3617 return;
3618
3619 Permutation a(W->interface().order());
3620 a.inverse();
3621
3622 /* at this point in_buf holds the full putative new interface; we
3623 need to check for reserved or repeated non-empty symbols */
3624
3625 const String* str = checkLeadingWhite(*in_buf);
3626
3627 if (str) {
3628 Error(LEADING_WHITESPACE,in_buf,&W->interface().inInterface(),&a,str);
3629 goto error_exit;
3630 }
3631
3632 str = checkReserved(*in_buf,W->interface());
3633
3634 if (str) {
3635 Error(RESERVED_SYMBOL,in_buf,&W->interface().inInterface(),&a,str);
3636 goto error_exit;
3637 }
3638
3639 if (!checkRepeated(*in_buf)) {
3640 Error(REPEATED_SYMBOL,in_buf,&W->interface().inInterface(),&a);
3641 goto error_exit;
3642 }
3643
3644 /* if we reach this point, the new interface is ok */
3645
3646 printf("new input symbols:\n\n");
3647 printInterface(stdout,*in_buf,a);
3648 printf("\n");
3649
3650 W->interface().setIn(*in_buf);
3651
3652 return;
3653
3654 error_exit:
3655 ERRNO = ERROR_WARNING;
3656 return;
3657 }
3658
out_entry()3659 void interface::out_entry()
3660
3661 /*
3662 Entry function to the output interface modification mode. The global variable
3663 in_buf is originally set to value for the current group.
3664 */
3665
3666 {
3667 delete in_buf;
3668 in_buf = new GroupEltInterface(W->interface().outInterface());
3669
3670 Permutation a(W->interface().order());
3671 a.inverse();
3672
3673 printf("current output symbols are the following :\n\n");
3674 printInterface(stdout,*in_buf,W->interface().inInterface(),a);
3675 printf("\n");
3676
3677 return;
3678 }
3679
out_exit()3680 void interface::out_exit()
3681
3682 /*
3683 Exit function for the output modification mode. No checking is necessary
3684 here.
3685 */
3686
3687 {
3688 if (in_buf == 0) // hack to prevent execution in special cases
3689 return;
3690
3691 Permutation a(W->interface().order());
3692 a.inverse();
3693
3694 printf("new output symbols:\n\n");
3695 printInterface(stdout,*in_buf,W->interface().inInterface(),a);
3696 printf("\n");
3697
3698 W->interface().setOut(*in_buf);
3699
3700 return;
3701 }
3702
3703 };
3704
3705 namespace {
3706
main_exit()3707 void main_exit()
3708
3709 /*
3710 Symmetric function to main_entry. Should undo what main_entry did.
3711 */
3712
3713 {
3714 delete W;
3715 wgraph_warning = true;
3716 return;
3717 }
3718
uneq_entry()3719 void uneq_entry()
3720
3721 {
3722 W->activateUEKL();
3723 return;
3724 }
3725
uneq_exit()3726 void uneq_exit()
3727
3728 /*
3729 We keep the unequal-parameter context, because one might want to go back
3730 and forth between the unequal and the ordinary case.
3731 */
3732
3733 {
3734 return;
3735 }
3736
3737 };
3738