Algorithm-AM

 view release on metacpan or  search on metacpan

AM.xs  view on Meta::CPAN

       *
       * and supralist[9] will become
       *
       * data:    3 0 subcontextnumber x y (now has three subcontexts)
       * count:   1
       * next:    7
       * touched: 0
       *
       * (note: the entries in data[] are added in decreasing order)
       *
       *
       * If, on the other hand, if supralist[lattice[d]] looks like
       *
       * data:    2 0 x y
       * count:   8
       * next:    11
       * touched: 1
       *
       * that means that supralist[11] must look something like
       *
       * data:    3 0 subcontextnumber x y
       * count:   4
       * next:    2
       * touched: 0
       *
       * There already exists a supracontext with subcontextnumber
       * added in!  So we change supralist[lattice[d]] to
       *
       * data:    2 0 x y
       * count:   7 (decrease by 1)
       * next:    11
       * touched: 1
       *
       * change supralist[11] to
       *
       * data:    3 0 subcontextnumber x y
       * count:   5 (increase by 1)
       * next:    2
       * touched: 0
       *
       * and set lattice[d] = 11.
       */

      subcontext[sublattice_index] = context;
      AM_SHORT gaps[16];
      if (context == 0) {
        AM_SUPRA *p;
        for (iter_supras(p, supralist)) {
          AM_SHORT *data;
          Newxz(data, p->data[0] + 3, AM_SHORT);
          Copy(p->data + 2, data + 3, p->data[0], AM_SHORT);
          data[2] = subcontextnumber;
          data[0] = p->data[0] + 1;
          Safefree(p->data);
          p->data = data;
        }
        if (lattice[context] == 0) {

          /* in this case, the subcontext will be
           * added to all supracontexts, so there's
           * no need to hassle with a Gray code and
           * move pointers
           */

          AM_SHORT count = 0;
          AM_SHORT ci = nptr[sublattice_index];
          nptr[sublattice_index] = supralist[ci].next;
          AM_SUPRA *c = supralist + ci;
          c->next = supralist->next;
          supralist->next = ci;
          Newxz(c->data, 3, AM_SHORT);
          c->data[2] = subcontextnumber;
          c->data[0] = 1;
          for (int i = 0; i < (1 << active); ++i) {
            if (lattice[i] == 0) {
              lattice[i] = ci;
              ++count;
            }
          }
          c->count = count;
        }
        continue;
      }

      /* set up traversal using Gray code */
      AM_SHORT d = context;
      AM_SHORT numgaps = 0;
      for (int i = 1 << (active - 1); i; i >>= 1) {
        if (!(i & context)) {
          gaps[numgaps++] = i;
        }
      }
      AM_SHORT t = 1 << numgaps;

      AM_SHORT pi = lattice[context];
      AM_SUPRA *p = supralist + pi;
      if (pi) {
        --(p->count);
      }
      AM_SHORT ci = nextsupra;
      nextsupra = supralist[ci].next;
      p->touched = 1;
      AM_SUPRA *c = supralist + ci;
      c->touched = 0;
      c->next = p->next;
      p->next = ci;
      c->count = 1;
      Newxz(c->data, p->data[0] + 3, AM_SHORT);
      Copy(p->data + 2, c->data + 3, p->data[0], AM_SHORT);
      c->data[2] = subcontextnumber;
      c->data[0] = p->data[0] + 1;
      lattice[context] = ci;

      /* traverse */
      while (--t) {
        AM_SHORT tt;
        int i;
        /* find the rightmost 1 in t; from HAKMEM, I believe */
        for (i = 0, tt = ~t & (t - 1); tt; tt >>= 1, ++i) {
          ;
        }



( run in 0.601 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )