コード例 #1
0
/*
 * Try to generate a fresh tuple of n values
 * - tau[i] = type for a[i]
 * - return false if this fails
 */
static bool gen_fresh_tuple(fresh_val_maker_t *maker, uint32_t n, type_t *tau, value_t *a) {
  type_table_t *types;
  value_table_t *vtbl;
  tuple_counter_t *ctr;
  uint32_t j;
  value_t v;

  types = maker->types;
  vtbl = maker->vtbl;

  // search for an infinite tau[j]
  for (j=0; j<n; j++) {
    if (! is_finite_type(types, tau[j])) {
      break;
    }
  }

  if (j < n) {
    // tau[j] is infinite
    fill_tuple(vtbl, n, tau, a, j);
    a[j] = make_fresh_value(maker, tau[j]);
    return true;
  }

  // all types are finite: try to get a fresh element
  // for one of tau[j]
  for (j=0; j<n; j++) {
    v = make_fresh_value(maker, tau[j]);
    if (v != null_value) break;
  }

  if (j < n) {
    // we have a fresh v of type tau[j]
    fill_tuple(vtbl, n, tau, a, j);
    a[j] = v;
    return true;
  }

  // all tau[i] are finite and saturated: use the counter
  ctr = get_tuple_counter(maker, n, tau);
  j = ctr->count;
  while (j < ctr->card && vtbl_test_object_tuple(vtbl, n, tau, j)) {
    j++;
  }
  if (j < ctr->card) {
    vtbl_gen_object_tuple(vtbl, n, tau, j, a);
    ctr->count = j+1;
    return true;
  }

  // failed
  ctr->count = j;
  return false;
}
コード例 #2
0
/*
 * Test
 * - create values of type tau
 * - n: max number of fresh values to try (assumed positive)
 */
static void test_type(type_t tau, uint32_t n) {
  value_t v;
  uint32_t i;

  printf("==== Test fresh values of type ");
  print_type(stdout, &types, tau);
  printf(" ====\n");
  printf("cardinality: %"PRIu32"\n\n", type_card(&types, tau));

  i = 0;
  do {
    v = make_fresh_value(&maker, tau);
    if (v == null_value) break;
    i ++;
    printf("val[%"PRIu32"] = ", i);
    vtbl_print_object(stdout, &vtbl, v);
    printf("\n");
    if (vtbl_queue_is_nonempty(&vtbl)) {
      vtbl_print_queued_functions(stdout, &vtbl, true);
      printf("\n");
    }
  } while (i <n);

  printf("\n---> got %"PRIu32" fresh values\n\n", i);
}
コード例 #3
0
value_t make_fresh_function(fresh_val_maker_t *maker, type_t tau) {
  value_t buffer[10];
  value_t a[2];
  value_t *aux;
  type_table_t *types;
  value_table_t *vtbl;
  function_type_t *d;
  tuple_counter_t *ctr;
  type_t sigma;
  value_t v;
  uint32_t i, n;

  types = maker->types;
  vtbl = maker->vtbl;

  d = function_type_desc(types, tau);;
  sigma = d->range;

  if (is_unit_type(types, sigma)) {
    // sigma is a singleton so there's only one function of type tau
    v = null_value;
    if (! vtbl_test_object(vtbl, tau, 0)) {
      v = vtbl_gen_object(vtbl, tau, 0);
    }
    return v;
  }

  // try to get a fresh value of type sigma
  // if this works create a new constant function
  v = make_fresh_value(maker, sigma);
  if (v != null_value) {
    v = vtbl_mk_function(vtbl, tau, 0, NULL, v);
    return v;
  }

  // sigma is finite and saturated
  v = null_value;
  if (card_of_domain_type(types, tau) > 2) {
    // try to get a fresh tuple in the domain
    n = d->ndom; // function arity
    aux = buffer;
    if (n > 10) {
      assert(n < UINT32_MAX/sizeof(value_t));
      aux = (value_t *) safe_malloc(n * sizeof(value_t));
    }

    if (gen_fresh_tuple(maker, n, d->domain, aux)) {
      /*
       * We have a fresh tuple aux[0 ... n-1].
       * We get two objects a[0] and a[1] of type sigma
       * and return the function f that maps every thing to a[0]
       * except aux[0 .. n-1] that's mapped a[1].
       * This f must be fresh.
       *
       * Take another g of type tau. Since aux is fresh,
       * then g(aux) is the default value for g.
       * - if g's default is not a[1], then g /= f
       * - if g's default is a[1] and there's an x /= aux such
       *   that g(x) = a[1] then g /= f (since f(x) = a[0]).
       * - otherwise,
       *   - the default for g is a[1]
       *   - for any other x in the domain g(x) /= a[1]
       *   - by construction, the default value for g is
       *     one that occurs most often in the range of g
       *     so g(x) /= g(y) whenever x /= y.
       *   - since the domain has cardinality > 2, there's
       *     a y such that g(y) /= a[0] and g(y) /= a[1] so g /= f
       *     in that case too.
       */
      if (! vtbl_make_two_objects(vtbl, sigma, a)) {
	assert(false); // should never happen
      }
      v = vtbl_mk_map(vtbl, n, aux, a[1]); // map (aux[0] ... aux[n-1] := a[1]);
      v = vtbl_mk_function(vtbl, tau, 1, &v, a[0]);
    }

    if (n > 10) {
      safe_free(aux);
    }
  }

  if (v == null_value) {
    /*
     * The previous trick has failed:
     * - sigma and tau[0 ... n-1] are all finite
     * - sigma and tau[0] x ... x tau[n-1] are saturated
     * Try the counter for tau
     */
    ctr = get_type_counter(maker, tau);
    i = ctr->count;
    while (i < ctr->card && vtbl_test_object(vtbl, tau, i)) {
      i ++;
    }
    if (i < ctr->card) {
      v = vtbl_gen_object(vtbl, tau, i);
      ctr->count = i+1;
    } else {
      // failed
      ctr->count = i;
      assert(v == null_value);
    }
  }

  return v;
}