예제 #1
0
	int PDCAN(int l, int v) {
		// we can easily construct a PDCAN with v odd or a prime power
		int s = ceil_log(l, PDCAN_v(v));
		return s * 2;
	}
예제 #2
0
/*
 * Force maps map[0 ... n-1] to be all distinct by updating them.
 * - store = particle store to create fresh indices
 * - f = type descriptor for all the maps in the array
 * - n must be positive
 *
 * Technique used:
 * - create fresh indices i_1,..,i_k in the domain of f
 * - create c values a_1,..., a_c in the range of f
 * such that (c ^ k) >= n.
 * Update map[t] by adding [i_1 -> a_t1, ..., i_k -> a_tk]
 * in such a way that (t1, ...., tk) differ from (u1, ..., uk) when u/=t.
 *
 * Return false if that's not possible (i.e., the number of functions
 * of the type f is finite and smaller than n).
 */
bool force_maps_to_differ(pstore_t *store, function_type_t *f, uint32_t n, map_t **map) {
  type_table_t *types;
  particle_t *idx;
  particle_t *a;
  uint32_t *tuple;
  type_t tau;
  uint32_t i, j, k, c;

  types = store->types;
  tau = f->range;

  if (is_unit_type(types, tau)) {
    return false;
  }

  if (is_finite_type(types, tau)) {
    c = type_card(types, tau);
    k = ceil_log(c, n);
  } else {
    c = n;
    k = 1;
  }

  assert(k>0 && c>0 && upower32(c, k) >= n);

  // tuple + index array are of size k
  // a is of size c
  tuple = (uint32_t *) safe_malloc(k * sizeof(uint32_t));
  idx = (particle_t *) safe_malloc(k * sizeof(particle_t));
  a = (particle_t *) safe_malloc(c * sizeof(particle_t));

  // initialize the idx array with fresh values
  if (f->ndom == 1) {
    for (i=0; i<k; i++) {
      idx[i] = get_new_particle(store, f->domain[0]);
      if (idx[i] == null_particle) goto failed;
    }
  } else {
    for (i=0; i<k; i++) {
      idx[i] = get_new_tuple(store, f->ndom, f->domain);
      if (idx[i] == null_particle) goto failed;
    }
  }

  // fill-in a with c distinct values of type tau
  for (i=0; i<c; i++) {
    a[i] = get_distinct_particle(store, tau, i, a);
    assert(a[i] != null_particle);
  }

  // initialize tuple = (0,...,0)
  for (i=0; i<k; i++) {
    tuple[i] = 0;
  }

  // update then normalize the maps
  i = 0;
  for (;;) {
    assert(i < n);
    for (j=0; j<k; j++) {
      assert(tuple[j] < c);
      add_elem_to_map(map[i], idx[j], a[tuple[j]]);
    }
    normalize_map(map[i]);
    i ++;
    if (i == n) break;
    tuple_successor(tuple, k, c);
  }

  safe_free(a);
  safe_free(idx);
  safe_free(tuple);
  return true;


 failed:
  safe_free(a);
  safe_free(idx);
  safe_free(tuple);
  return false;
}