示例#1
0
// check whether the subtree rooted at x is ordered
static bool is_ordered(rba_buffer_t *b, uint32_t x) {
  uint32_t i, j;
  pprod_t *r, *s, *t;

  assert(x < b->num_nodes);

  if (x == 0) return true;

  i = b->child[x][0];  // left child
  j = b->child[x][1];  // right child
  r = b->mono[x].prod;
  s = b->mono[i].prod;
  t = b->mono[j].prod;

  // the expected order is s < r < t
  if (i != 0 && !pprod_precedes(s, r)) {
    printf("tree not ordered at node %"PRIu32" (for left child %"PRIu32")\n", x, i);
    fflush(stdout);
    return false;
  }

  if (j != 0 && !pprod_precedes(r, t)) {
    printf("tree not ordered at node %"PRIu32" (for right child = %"PRIu32")\n", x, j);
    fflush(stdout);
    return false;
  }

  return is_ordered(b, i) && is_ordered(b, j);
}
示例#2
0
/*
 * Add a * r * b1 to b
 */
void arith_buffer_add_mono_times_buffer(arith_buffer_t *b, arith_buffer_t *b1, rational_t *a, pprod_t *r) {
  mlist_t *p, *aux, *p1;
  mlist_t **q;
  pprod_t *r1;

  q = &b->list;
  p = *q;

  p1 = b1->list;
  while (p1->next != NULL) {
    r1 = pprod_mul(b->ptbl, p1->prod, r);
    while (pprod_precedes(p->prod, r1)) {
      q = &p->next;
      p = *q;
    }

    if (p->prod == r1) {
      q_addmul(&p->coeff, &p1->coeff, a);
      q = &p->next;
      p = *q;
    } else {
      assert(pprod_precedes(r1, p->prod));

      aux = alloc_list_elem(b->store);
      aux->next = p;
      q_addmul(&aux->coeff, &p1->coeff, a); // since aux->coeff is 0 initially
      aux->prod = r1;

      *q = aux;
      q = &aux->next;
      b->nterms ++;
    }
    p1 = p1->next;
  }
}
示例#3
0
/*
 * Add -r to b
 */
void arith_buffer_sub_pp(arith_buffer_t *b, pprod_t *r) {
  mlist_t *p, *aux;
  mlist_t **q;

  q = &b->list;
  p = *q;
  assert(p == b->list);
  while (pprod_precedes(p->prod, r)) {
    q = &p->next;
    p = *q;
  }

  // p points to a monomial with p->prod >= r
  // q is either &p->list or &p0->next where p0 is p's predecessor
  if (p->prod == r) {
    q_sub_one(&p->coeff);
  } else {
    assert(pprod_precedes(r, p->prod));

    aux = alloc_list_elem(b->store);
    aux->next = p;
    q_set_minus_one(&aux->coeff);
    aux->prod = r;

    *q = aux;
    b->nterms ++;
  }
}
示例#4
0
/*
 * Add - r * b1 to b
 */
void arith_buffer_sub_pp_times_buffer(arith_buffer_t *b, arith_buffer_t *b1, pprod_t *r) {
  mlist_t *p, *aux, *p1;
  mlist_t **q;
  pprod_t *r1;

  q = &b->list;
  p = *q;

  p1 = b1->list;
  while (p1->next != NULL) {
    r1 = pprod_mul(b->ptbl, p1->prod, r);
    while (pprod_precedes(p->prod, r1)) {
      q = &p->next;
      p = *q;
    }

    if (p->prod == r1) {
      q_sub(&p->coeff, &p1->coeff);
      q = &p->next;
      p = *q;
    } else {
      assert(pprod_precedes(r1, p->prod));

      aux = alloc_list_elem(b->store);
      aux->next = p;
      q_set_neg(&aux->coeff, &p1->coeff);
      aux->prod = r1;

      *q = aux;
      q = &aux->next;
      b->nterms ++;
    }
    p1 = p1->next;
  }
}
示例#5
0
/*
 * Add -a * r to b
 */
void arith_buffer_sub_mono(arith_buffer_t *b, rational_t *a, pprod_t *r) {
  mlist_t *p, *aux;
  mlist_t **q;

  if (q_is_zero(a)) return;

  q = &b->list;
  p = *q;
  assert(p == b->list);
  while (pprod_precedes(p->prod, r)) {
    q = &p->next;
    p = *q;
  }

  // p points to a monomial with p->prod >= r
  // q is &b->list if p is first in the list
  // q is &p0->next where p0 = predecessor of p otherwise.
  if (p->prod == r) {
    q_sub(&p->coeff, a);
  } else {
    assert(pprod_precedes(r, p->prod));

    aux = alloc_list_elem(b->store);
    aux->next = p;
    q_set_neg(&aux->coeff, a);
    aux->prod = r;

    *q = aux;
    b->nterms ++;
  }
}
示例#6
0
/*
 * Monomial of p whose pp equals r (or NULL)
 */
mlist_t *arith_buffer_get_mono(arith_buffer_t *b, pprod_t *r) {
  mlist_t *p;

  p = b->list;
  while (pprod_precedes(p->prod, r)) {
    p = p->next;
  }

  if (p->prod == r) {
    return p;
  } else {
    assert(pprod_precedes(r, p->prod));
    return NULL;
  }
}
示例#7
0
/*
 * Add poly to buffer b
 */
void arith_buffer_add_monarray(arith_buffer_t *b, monomial_t *poly, pprod_t **pp) {
  mlist_t *p, *aux;
  mlist_t **q;
  pprod_t *r1;

  assert(good_pprod_array(poly, pp));

  q = &b->list;
  p = *q;

  while (poly->var < max_idx) {
    // poly points to a pair (coeff, x_i)
    // r1 = power product for x_i
    r1 = *pp;
    while (pprod_precedes(p->prod, r1)) {
      q = &p->next;
      p = *q;
    }

    // p points to monomial whose prod is >= r1 in the deg-lex order
    // q is either &b->list or &p0->next where p0 is the predecessor
    // of p in the list
    if (p->prod == r1) {
      q_add(&p->coeff, &poly->coeff);
      q = &p->next;
      p = *q;
    } else {
      assert(pprod_precedes(r1, p->prod));

      aux = alloc_list_elem(b->store);
      aux->next = p;
      q_set(&aux->coeff, &poly->coeff);
      aux->prod = r1;

      *q = aux;
      q = &aux->next;
      b->nterms ++;
    }

    // move to the next monomial of poly
    poly ++;
    pp ++;
  }
}
示例#8
0
/*
 * Subtract a * poly from b
 */
void arith_buffer_sub_mono_times_monarray(arith_buffer_t *b, monomial_t *poly, pprod_t **pp, rational_t *a, pprod_t *r) {
  mlist_t *p, *aux;
  mlist_t **q;
  pprod_t *r1;

  assert(good_pprod_array(poly, pp));

  q = &b->list;
  p = *q;

  while (poly->var < max_idx) {
    // poly points to a pair (coeff, x_i)
    // r1 = r * power product for x_i
    r1 = pprod_mul(b->ptbl, *pp, r);
    while (pprod_precedes(p->prod, r1)) {
      q = &p->next;
      p = *q;
    }

    // p points to monomial whose prod is >= r1 in the deg-lex order
    // q points to the predecessor of p in the list
    if (p->prod == r1) {
      q_submul(&p->coeff, &poly->coeff, a);
      q = &p->next;
      p = *q;
    } else {
      assert(pprod_precedes(r1, p->prod));

      aux = alloc_list_elem(b->store);
      aux->next = p;
      q_submul(&aux->coeff, &poly->coeff, a); // aux->coeff is initialized to 0 in alloc_list_elem
      aux->prod = r1;

      *q = aux;
      q = &aux->next;
      b->nterms ++;
    }

    // move to the next monomial of poly
    poly ++;
    pp ++;
  }
}
示例#9
0
/*
 * Add b1 to b
 */
void arith_buffer_add_buffer(arith_buffer_t *b, arith_buffer_t *b1) {
  mlist_t *p, *aux, *p1;
  mlist_t **q;
  pprod_t *r1;

  assert(b->ptbl == b1->ptbl);

  q = &b->list;
  p = *q;

  p1 = b1->list;
  while (p1->next != NULL) {
    r1 = p1->prod;
    while (pprod_precedes(p->prod, r1)) {
      q = &p->next;
      p = *q;
    }

    if (p->prod == r1) {
      q_add(&p->coeff, &p1->coeff);
      q = &p->next;
      p = *q;
    } else {
      assert(pprod_precedes(r1, p->prod));

      aux = alloc_list_elem(b->store);
      aux->next = p;
      q_set(&aux->coeff, &p1->coeff);
      aux->prod = r1;

      *q = aux;
      q = &aux->next;
      b->nterms ++;
    }
    p1 = p1->next;
  }
}
示例#10
0
/*
 * Add (-a) * b1 to b
 */
void arith_buffer_sub_const_times_buffer(arith_buffer_t *b, arith_buffer_t *b1, rational_t *a) {
  mlist_t *p, *aux, *p1;
  mlist_t **q;
  pprod_t *r1;

  q = &b->list;
  p = *q;

  p1 = b1->list;
  while (p1->next != NULL) {
    r1 = p1->prod;
    while (pprod_precedes(p->prod, r1)) {
      q = &p->next;
      p = *q;
    }

    if (p->prod == r1) {
      q_submul(&p->coeff, &p1->coeff, a);
      q = &p->next;
      p = *q;
    } else {
      assert(pprod_precedes(r1, p->prod));

      // aux->coeff is initialized to 0 in alloc_list_elem
      aux = alloc_list_elem(b->store);
      aux->next = p;
      q_submul(&aux->coeff, &p1->coeff, a);
      aux->prod = r1;

      *q = aux;
      q = &aux->next;
      b->nterms ++;
    }
    p1 = p1->next;
  }
}
示例#11
0
/*
 * For debugging: check that q contains valid power products
 * sorted in increasing deg-lex ordering.
 */
static bool good_pprod_array(monomial_t *poly, pprod_t **pp) {
  pprod_t *r;

  if (poly->var < max_idx) {
    r = *pp;
    poly ++;
    pp ++;
    while (poly->var < max_idx) {
      if (! pprod_precedes(r, *pp)) return false;
      r = *pp;
      pp ++;
      poly ++;
    }
  }

  return true;
}
示例#12
0
int main() {
  pprod_t *p1, *p2;
  uint32_t i, j;
  int32_t cmp;

  p[0] = empty_pp;
  p[1] = var_pp(0);
  p[2] = var_pp(1);
  p[3] = var_pp(0x3fffffff);

  init_pp_buffer(&buffer, 0);
  p[4] = pp_buffer_getprod(&buffer);  // empty

  pp_buffer_reset(&buffer);
  pp_buffer_mul_var(&buffer, 0);
  p[5] = pp_buffer_getprod(&buffer); // x_0

  pp_buffer_reset(&buffer);
  pp_buffer_mul_var(&buffer, 0);
  pp_buffer_mul_var(&buffer, 1);
  pp_buffer_mul_var(&buffer, 0);
  p[6] = pp_buffer_getprod(&buffer);  // x_0^2 x_1

  pp_buffer_reset(&buffer);
  pp_buffer_mul_varexp(&buffer, 1, 2);
  pp_buffer_mul_varexp(&buffer, 4, 3);
  p[7] = pp_buffer_getprod(&buffer);  // x_1^2 x_4^3

  pp_buffer_set_varexp(&buffer, 3, 2);
  pp_buffer_mul_varexp(&buffer, 1, 4);
  p[8] = pp_buffer_getprod(&buffer);   // x_3^2 x_1^4

  pp_buffer_set_pprod(&buffer, p[7]);
  pp_buffer_mul_pprod(&buffer, p[1]);
  pp_buffer_mul_pprod(&buffer, p[8]);
  p[9] = pp_buffer_getprod(&buffer);

  for (i=0; i<NUM_PRODS; i++) {
    printf("p[%"PRIu32"] =  ", i);
    print_pprod(stdout, p[i]);
    printf(" total degree = %"PRIu32"\n", pprod_degree(p[i]));
    for (j=0; j<5; j++) {
      printf(" degree of x_%"PRIu32" = %"PRIu32"\n", j, pprod_var_degree(p[i], j));
    }
    printf("----\n");
  }
  printf("\n");

  for (i=0; i<NUM_PRODS; i++) {
    p1 = p[i];
    for (j=0; j<NUM_PRODS; j++) {
      p2 = p[j];
      printf("p1: ");
      print_pprod0(stdout, p1);
      printf("p2: ");
      print_pprod0(stdout, p2);
      if (pprod_equal(p1, p2)) {
	printf("equal products\n");
      }
      if (pprod_divides(p1, p2)) {
	printf("p1 divides p2\n");
      }
      if (pprod_divisor(&buffer, p1, p2)) {
	printf("p2/p1: ");
	print_pp_buffer0(stdout, &buffer);
      }
      if (pprod_divides(p2, p1)) {
	printf("p2 divides p1\n");
      }
      if (pprod_divisor(&buffer, p2, p1)) {
	printf("p1/p2: ");
	print_pp_buffer0(stdout, &buffer);
      }
      cmp = pprod_lex_cmp(p1, p2);
      if (cmp < 0) {
	printf("p1 < p2 in lex order\n");
      } else if (cmp > 0) {
	printf("p1 > p2 in lex order\n");
      } else {
	printf("p1 = p2 in lex order\n");
      }
      if (pprod_precedes(p1, p2)) {
	printf("p1 < p2 in deglex ordering\n");
      }
      if (pprod_precedes(p2, p1)) {
	printf("p2 < p1 in deglex ordering\n");
      }
      printf("----\n");
    }
  }


  for (i=0; i<10; i++) {
    free_pprod(p[i]);
  }

  delete_pp_buffer(&buffer);

  return 0;
}