File: bound.c

package info (click to toggle)
libhomfly 1.02r6-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 220 kB
  • sloc: ansic: 1,740; makefile: 19; sh: 1
file content (276 lines) | stat: -rw-r--r-- 9,239 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
/*
------------------------------------------------------------------------------
  BOUND.C
  By Bob Jenkins, in association with his Masters Thesis
  Routines dealing with boundary manipulations of weaves
  Public Domain
------------------------------------------------------------------------------
*/
#include <stdlib.h>
#include <gc.h>

#include "standard.h"
#include "order.h"
#include "control.h"
#include "bound.h"

/*
------------------------------------------------------------------------------
B_MANIP computes values of the global boundary variables.
A step is either adding a crossing, adding a crossing and removing a pair of
boundary crossings, or just removing a pair of boundary crossings.
------------------------------------------------------------------------------
*/
word list[BIGWEAVE];              /* description of first new weave */
word list2[BIGWEAVE];           /* description of second, if needed */
word old_going_in[BIGWEAVE];/* Was *i* an input? *old_going_in[i]*. */
word going_in[BIGWEAVE];    /* Will *i* be an input? *going_in[i]*. */
word map[BIGWEAVE];   /* i of old weave becomes map[i] of new weave */
word first;                    /* first boundary crossing to remove */
word second;                  /* second boundary crossing to remove */
word right;          /* Is the crossing being added be righthanded? */
word oldcross;     /* number of boundary crossings in the old weave */
word newcross;    /* number of boundary crossings in each new weave */
word oldin;                    /* number of inputs to the old weave */
word newin;                    /* number of inputs to the new weave */

void b_manip(weave *oldweaves)
{
  word       i, j, k;
  ub4        boundary[2];

  oldcross = plan.oldn;             /* number of original boundary crossings */
  oldin = oldcross/2;                           /* number of original inputs */
  newcross = plan.newn;  /* number of boundary crossings in resulting weaves */
  newin = newcross/2;                                          /* " inputs " */

  /*--------------------------------------------------- Compute old_going_in */
  for (i = 0; !oldweaves[i].tag.len; i++) ;          /* find a defined weave */
  boundary[0] = oldweaves[i].boundary[0];
  boundary[1] = oldweaves[i].boundary[1];
  for (i = 0; i < oldcross; i++)
    old_going_in[i] = 1;                 /* pretend all crossings are inputs */
  for (i = 0; i < oldin; i++)
  {
    k = (i < 6) ? 0 : 1;
    if (old_going_in[(boundary[k] & 0x1f)] == 0) {
      printf("cannot have both ends of a string be an output\n");
    }
    old_going_in[(boundary[k] & 0x1f)] = 0;            /* unmark the outputs */
    boundary[k] >>= 5;
  }
  right = plan.right;
  if (plan.which != -1)
  {
    for (i = 0; i < oldcross; ++i)
    {
      if (old_going_in[i] != plan.going_in[i]) {
	printf("going_in is messed up\n");
	break;
      }
    }
  }

  /*--------------------------- Set first and second, if they need to be set */
  first  = plan.r0[0];
  second = plan.r1[0];
  if (plan.reductions && plan.which != -1)   /* crossing added, pair removed */
  {
    if (first > plan.which+1) --first;
    if (second > plan.which+1) --second;
    if (first > plan.which) --first;
    if (second > plan.which) --second;
  }
  else ;                                  /* crossing added, no pair removed */

  /*---------------------------------------------------------------- Set map */
  if (plan.reductions == 0)
  {
    for (i = 0, j = 0; i < oldcross+2; ++i)
      if ((i != plan.which) && (i != plan.which+2)) map[j++] = i;
  }
  else if (plan.which == (-1))
  {
    for (i = 0, j = 0; j < oldcross; ++j)
      if ((j != plan.r0[0]) && (j != plan.r1[0])) map[j] = i++;
  }
  else if (plan.r0[0] > plan.r1[0])
  {
    for (i = 0; i < oldcross; i++) map[i] = i;
    map[first]  = (second);
    map[second] = (first);
  }
  else if (plan.which == 0)
  {
    for (i = 0; i < oldcross; i++) map[i] = i+1;
    map[0]   = 0;
    map[oldcross-1] = 1;
  }
  else
  {
    for (i = 0; i < oldcross; i++) map[i] = i-1;
    map[0]          = oldcross-2;
    map[oldcross-1] = oldcross-1;
  }

  /*----------------------------------------------------------- Set going_in */
  if (plan.which != (-1))
  {
    for (i = 0; i < oldcross; i++)
    {
      going_in[map[i]] = old_going_in[i];
    }
  }
  else
  {
    for (i = 0; i < oldcross; i++)
    {
      if ((i != first) && (i != second))
      {
        going_in[map[i]] = old_going_in[i];
      }
    }
  }

  if (plan.reductions == 0)
  {
    going_in[plan.which]   = plan.prev;
    going_in[plan.which+2] = !plan.prev;
  }
}




/*
------------------------------------------------------------------------------
B_NO_PAIRS adds a single crossing to a single weave.
Either the crossing is correct, in which case *one* will be set, or it is
wrong.  In this case no more than two weaves are needed, so *two* will be set.
------------------------------------------------------------------------------
*/
void  b_no_pairs(word  *list,  /* list of original inputs/outputs, modified by this routine */
                 word  *list2,                    /* inputs/outputs of the second new weave */
                 word  *one,                                 /* will one new weave suffice? */
                 word  *two)                                /* will two new weaves suffice? */
{
  word  i,
        a,
        b,
        c;


  /*-------------------------------------------------- Make the new boundary */
  for (i = oldcross; --i >= 0;) list[map[i]] = map[list[i]];
  a         = plan.which+1;
  list[a-1] = a+1;
  list[a+1] = a-1;

  /*------------------------- Decide if the crossing needs to be operated on */
  c = a-1;
  b_right(list, going_in, c, a, i);
  *one = (i == right);
  *two = !*one;
  if (*two)
  {
    for (i = newcross; --i >= 0;) list2[i] = list[i];
    b               = (plan.prev == going_in[a]) ? a-1 : a+1;
    c               = (plan.prev == going_in[a]) ? a+1 : a-1;
    list2[list2[a]] = b;
    list2[b]        = list2[a];
    list2[a]        = c;
    list2[c]        = a;
  }
}



/*
------------------------------------------------------------------------------
B_ONE_PAIR handles adding one crossing and removing one pair of boundary
crossings.  This may require replacing the original weave with one, two, or
more new weaves.  If more than two are needed, do not set *one* or *two*.
------------------------------------------------------------------------------
*/
void b_one_pair(list, list2, one, two)
word  *list;    /* list of original inputs/outputs, modified by this routine */
word  *list2;                      /* inputs/outputs of the second new weave */
word  *one;                                   /* will one new weave suffice? */
word  *two;                                  /* will two new weaves suffice? */
{
  word   a;
  word   i;
  word   crossed;
  word   shouldBeRight;
  word   temp[BIGWEAVE];

  /*---------------------------------- Check for a couple easy to spot cases */
  a = plan.which;
  if ((plan.r0[0] == a+1) || (plan.r1[0] == a+1))
  {                                            /* A Type I Reidemeister move */
    *one = 1;
    return;
  }

  /*---------------- Handle the cases where the reduction is the 0..n-1 jump */
  if (plan.r0[0] < plan.r1[0])
  {
    if (old_going_in[0] && old_going_in[oldcross-1]) return;
    crossed = b_cross(first, second, list[first], list[second]);
    b_right(list, old_going_in, first, second, shouldBeRight);
                                                              /* werecrossed */
    if (list[first] == second)
    {
        /* A Type I Reidemeister move */
      for (i = oldcross; --i >= 0; ) temp[map[i]] = list[i];
      for (i = oldcross; --i >= 0; ) list[i] = map[temp[i]];
      *one = 1;
      return;
    }

    if (old_going_in[first] != old_going_in[second])
    {
        /* this may be complicated */
        return;
    }

    for (i = oldcross; --i >= 0; ) temp[map[i]] = list[i];
    for (i = oldcross; --i >= 0; ) list[i] = map[temp[i]];
    if (!old_going_in[first] && !old_going_in[second] &&
        (crossed ^ shouldBeRight ^ right))
    {
      *two = 1;
      for (i = 0; i < newcross; i++) list2[i] = list[i];
      if (plan.which == 0) b_switch(list2, 1, 0, i);
      else b_switch(list2, newcross-1, newcross-2, i);
    }
    else *one = 1;
    return;
  }

  /*-------- Handle the cases where the numbers on the boundary are adjacent */
  if (list[first] == second)                   /* A Type I Reidemeister move */
  {
    *one = 1;
    return;
  }
  crossed = b_cross(first, second, list[first], list[second]);/* werecrossed */
  b_right(list, old_going_in, first, second, a); /* old crossing righthanded */
  b_switch(list, first, second, i);         /* switch the boundary crossings */
  b_right(list, going_in, first, second, i);    /* new should be righthanded */
  *one = (((crossed) && (a != right)) || ((!crossed) && (i == right)));
  if (*two = !*one)
  {
    if (old_going_in[first] != old_going_in[second])
    {
      *two = 0;
      b_switch(list, first, second, i);
    }
    else
    {
      for (i = newcross; --i >= 0; ) list2[i] = list[i];
      b_switch(list2, first, second, i);
    }
  }
}