1 /****************************************************************************
2 **
3 *A  collect_word.c              ANUPQ source                   Eamonn O'Brien
4 **
5 *Y  Copyright 1995-2001,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
6 *Y  Copyright 1995-2001,  School of Mathematical Sciences, ANU,     Australia
7 **
8 */
9 
10 #include "pq_defs.h"
11 #include "pcp_vars.h"
12 #include "pq_functions.h"
13 #include "constants.h"
14 #include "word_types.h"
15 
16 /* collect word in pcp generators of group; word has base address ptr;
17    set up the result as exponent vector with base address cp */
18 
collect_word(int ptr,int cp,struct pcp_vars * pcp)19 void collect_word(int ptr, int cp, struct pcp_vars *pcp)
20 {
21    register int *y = y_address;
22 
23    int temp;
24    int gen, exp;
25    register int i;
26    register int lastg = pcp->lastg;
27    register int length = y[ptr];
28 
29    /* zero out lastg entries in array in order to store result */
30    for (i = 1; i <= lastg; ++i)
31       y[cp + i] = 0;
32 
33    /* collect the word */
34    for (i = 2; i <= length; ++i) {
35       if ((gen = y[ptr + i]) > 0)
36          collect(gen, cp, pcp);
37       else
38          invert_generator(-gen, 1, cp, pcp);
39    }
40 
41    /* now calculate the appropriate power of the collected part */
42    if ((exp = y[ptr + 1]) != 1) {
43       temp = ptr + y[ptr] + 1;
44       calculate_power(exp, temp, cp, pcp);
45    }
46 }
47 
48 /* calculate the exp power of word stored as exponent-vector at cp;
49    ptr is index of free position for temporary storage in y */
calculate_power(int exp,int ptr,int cp,struct pcp_vars * pcp)50 void calculate_power(int exp, int ptr, int cp, struct pcp_vars *pcp)
51 {
52    register int *y = y_address;
53 
54    register int i;
55    register int lastg = pcp->lastg;
56 
57    power(abs(exp), cp, pcp);
58 
59    /* if necessary, calculate the inverse */
60    if (exp < 0) {
61       ++ptr;
62       vector_to_word(cp, ptr, pcp);
63       for (i = 1; i <= lastg; ++i)
64          y[cp + i] = 0;
65       invert_word(ptr, cp, pcp);
66    }
67 }
68 
69 /* collect a word in pcp generators which may be already stored
70    or is read in as string with base address ptr; store the result
71    as an exponent vector at cp; convert exponent vector
72    to string with base address ptr; and print out result */
73 
setup_word_to_collect(FILE * file,int format,int type,int cp,struct pcp_vars * pcp)74 void setup_word_to_collect(
75     FILE *file, int format, int type, int cp, struct pcp_vars *pcp)
76 {
77    int disp = pcp->lastg + 2;
78    register int ptr;
79 
80    ptr = pcp->lused + 1 + disp;
81 
82    if (type != FIRST_ENTRY && type != NEXT_ENTRY) {
83       if (format == BASIC)
84          read_word(file, disp, type, pcp);
85       else
86          pretty_read_word(file, disp, type, pcp);
87    }
88 
89    collect_word(ptr, cp, pcp);
90 
91    if (type == VALUE_A || type == VALUE_B || file != stdin)
92       return;
93 
94    setup_word_to_print("result of collection", cp, ptr, pcp);
95 }
96