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; }
/* * 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; }