00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 #include <memory.h>
00078 #include "udanax.h"
00079
00087
00088 void
00089 dspadd(
00090 typedsp *a,
00091 typewisp *b,
00092 typedsp *c,
00093 int enftype)
00094
00095
00096
00097 {
00098 lockadd(a->dsas, b->dsas, c->dsas, (unsigned)dspsize(enftype));
00099 }
00100
00108 void
00109 dspsub(
00110 typedsp *a,
00111 typewisp *b,
00112 typedsp *c,
00113 int enftype)
00114 {
00115 locksubtract(a->dsas, b->dsas, c->dsas, (unsigned)dspsize(enftype));
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00134
00135 bool
00136 setwispupwards(
00137 typecuc *ptr,
00138 int testflag)
00139 {
00140 typecuc *father;
00141
00142 int ntimeschanged = 0;
00143
00144
00145 if (!ptr)
00146 return 0;
00147
00148 typecuc *oldptr = ptr;
00149
00150 bool changed;
00151 for (changed = true; changed && ptr; ptr = father) {
00152 father = findfather((typecorecrum *) ptr);
00153 changed = setwisp((typecorecrum *) ptr);
00154 if (changed)
00155 ntimeschanged += 1;
00156 }
00157
00158 if (ntimeschanged)
00159 ivemodified((typecorecrum *) oldptr);
00160
00161 #ifndef DISTRIBUTION
00162 if (testflag)
00163 asserttreeisok((typecorecrum *) oldptr);
00164 #endif
00165
00166 return 0 != ntimeschanged;
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 #define widopseq(a,b,c) lockadd((a)->dsas,(b)->dsas,(c)->dsas,widsize(GRAN))
00182
00190
00191 static bool
00192 setwidseq(
00193 typecuc *father)
00194 {
00195 typecorecrum *ptr;
00196
00197 if (father->height == 0)
00198 return false;
00199
00200 typewid sum;
00201 clear(&sum, sizeof(sum));
00202
00203 for (ptr = findleftson(father); ptr; ptr = getrightbro(ptr))
00204 widopseq(&sum, &ptr->cwid, &sum);
00205
00206 if (lockeq(sum.dsas, father->cwid.dsas, (unsigned) widsize(father->cenftype)))
00207 return false;
00208
00209 movewisp(&sum, &father->cwid);
00210 ivemodified((typecorecrum *) father);
00211
00212 return true;
00213 }
00214
00222 static void
00223 lockmin(
00224 Tumbler *lock1,
00225 Tumbler *lock2,
00226 Tumbler *lock3,
00227 unsigned loxize)
00228 {
00229 while (loxize--) {
00230 macrotumblermin(lock1, lock2, lock3);
00231 lock1++;
00232 lock2++;
00233 lock3++;
00234 }
00235 }
00236
00244 static void
00245 lockmax(
00246 Tumbler *lock1,
00247 Tumbler *lock2,
00248 Tumbler *lock3,
00249 unsigned loxize)
00250 {
00251 while (loxize--) {
00252 macrotumblermax(lock1, lock2, lock3);
00253 lock1++;
00254 lock2++;
00255 lock3++;
00256 }
00257 }
00258
00266 static void
00267 didntchangewisps()
00268 {
00269 }
00270
00278
00279 static bool
00280 setwispnd(
00281 typecuc *father)
00282 {
00283 typecorecrum *ptr;
00284 typedsp newdsp, mindsp;
00285 typewid newwid, tempwid;
00286 bool lockiszerop;
00287 bool somethingchangedp = false;
00288
00289 if (father->height == 0)
00290 return false;
00291
00292
00293 if ((ptr = findleftson(father)) == NULL) {
00294 #ifndef DISTRIBUTION
00295 assert(0);
00296 clear(&father->cdsp, sizeof(father->cdsp));
00297 clear(&father->cwid, sizeof(father->cwid));
00298 ivemodified((typecorecrum *) father);
00299 return true;
00300 #else
00301 assert(0);
00302 #endif
00303 }
00304
00305
00306 movewisp(&ptr->cdsp, &mindsp);
00307 for (ptr = getrightbro(ptr); ptr; ptr = getrightbro(ptr))
00308 lockmin((Tumbler *) & mindsp, (Tumbler *) & ptr->cdsp, (Tumbler *) & mindsp, (unsigned)dspsize(ptr->cenftype));
00309
00310 lockiszerop = iszerolock((Tumbler *) & mindsp, (unsigned)dspsize(father->cenftype));
00311 if (!lockiszerop) {
00312 somethingchangedp = true;
00313 dspadd(&father->cdsp, &mindsp, &newdsp, (int) father->cenftype);
00314 } else
00315 movewisp(&father->cdsp, &newdsp);
00316
00317
00318
00319
00320 clear(&newwid, sizeof(newwid));
00321 for (ptr = findleftson(father); ptr; ptr = getrightbro(ptr)) {
00322 if (!lockiszerop) {
00323 ptr->modified = true;
00324 dspsub(&ptr->cdsp, &mindsp, &ptr->cdsp, (int) ptr->cenftype);
00325 }
00326
00327 lockadd((Tumbler *) & ptr->cdsp, (Tumbler *) & ptr->cwid, (Tumbler *) & tempwid,
00328 (unsigned)widsize(ptr->cenftype));
00329 lockmax((Tumbler *) & newwid, (Tumbler *) & tempwid, (Tumbler *) & newwid, (unsigned) widsize(ptr->cenftype));
00330 }
00331
00332 if (!somethingchangedp && !lockeq((Tumbler *) & newwid, (Tumbler *) & father->cwid, (unsigned) widsize(father->cenftype)))
00333 somethingchangedp = true;
00334
00335
00336 if (!somethingchangedp) {
00337 didntchangewisps();
00338 return false;
00339 }
00340
00341 movewisp(&newdsp, &father->cdsp);
00342 movewisp(&newwid, &father->cwid);
00343 ivemodified((typecorecrum *) father);
00344
00345 return true;
00346 }
00347
00355
00356 bool
00357 setwisp(
00358 typecorecrum *ptr)
00359 {
00360 if (ptr->height == 0)
00361 return false;
00362
00363 switch (ptr->cenftype) {
00364 case GRAN:
00365 return setwidseq((typecuc *) ptr);
00366 case SPAN:
00367 case POOM:
00368 return setwispnd((typecuc *) ptr);
00369 default:
00370 assert(0);
00371 }
00372
00373 return -1;
00374 }
00375
00383
00384 void
00385 setwidnd(
00386 typecuc *father)
00387 {
00388 typecorecrum *ptr;
00389 typewid newwid;
00390
00391 for (ptr = findleftson(father); ptr; ptr = getrightbro(ptr)) {
00392 clear(&newwid, sizeof(newwid));
00393 lockmax((Tumbler *) &newwid, (Tumbler *) &ptr->cwid, (Tumbler *) &newwid, (unsigned) widsize(ptr->cenftype));
00394 }
00395
00396 if (!lockeq((Tumbler *) &father->cwid, (Tumbler *) &newwid, (unsigned) widsize(father->cenftype))) {
00397 movewisp(&newwid, &father->cwid);
00398 ivemodified((typecorecrum *) father);
00399 }
00400 }
00401
00409
00410
00411
00412 bool
00413 iszerolock(
00414 Tumbler *lock,
00415 unsigned loxize)
00416 {
00417 while (loxize--)
00418 if (!iszerotumbler(lock++))
00419 return false;
00420
00421 return true;
00422 }
00423
00431 bool
00432 lockeq(
00433 Tumbler *lock1,
00434 Tumbler *lock2,
00435 unsigned loxize)
00436 {
00437 while (loxize--)
00438 if (!tumblereq(lock1++, lock2++))
00439 return false;
00440
00441 return true;
00442 }
00443
00451 void
00452 lockadd(
00453 Tumbler *lock1,
00454 Tumbler *lock2,
00455 Tumbler *lock3,
00456 unsigned loxize)
00457
00458 {
00459 while (loxize--)
00460 tumbleradd(lock1++, lock2++, lock3++);
00461 }
00462
00470 void
00471 locksubtract(
00472 Tumbler *lock1,
00473 Tumbler *lock2,
00474 Tumbler *lock3,
00475 unsigned loxize)
00476 {
00477 while (loxize--)
00478 tumblersub(lock1++, lock2++, lock3++);
00479 }
00480
00488
00489 bool
00490 lockis1story(
00491 Tumbler *lock,
00492 unsigned loxize)
00493 {
00494 while (loxize--)
00495 if (!is1story(lock++))
00496 return false;
00497
00498 return true;
00499 }