示例#1
0
int
noll_pure_add_dform (noll_pure_t * form, noll_dform_t * df)
{
  assert (form != NULL);
  assert (df != NULL);
  if (form->data == NULL)
    form->data = noll_dform_array_new ();
  noll_dform_array_push (form->data, df);
  return 1;
}
示例#2
0
/**
 * @brief Update the data constraints in @g with eq constraints.
 * 
 * The (in-)equality constraints on data are pushed.
 */
void
noll_graph_sat_dform (noll_graph_t * g)
{
  assert (g != NULL);

  if (g->data == NULL)
    g->data = noll_dform_array_new ();
  noll_dform_array *res = g->data;
  // go through all equality constraints and push them for data
  for (uint_t vi = 1;           // ignore 'nil' 
       vi < noll_vector_size (g->lvars); vi++)
    {
      noll_type_t *ty_vi = noll_var_type (g->lvars, vi);
      if (ty_vi->kind == NOLL_TYP_RECORD)
        continue;
      // it is a data variable
      // see relation of vi with all other data variables vj
      for (uint_t vj = vi + 1;  // ignore 'nil' 
           vj < noll_vector_size (g->lvars); vj++)
        {
          noll_type_t *ty_vj = noll_var_type (g->lvars, vj);
          if ((ty_vj->kind == NOLL_TYP_RECORD)
              || (ty_vi->kind != ty_vj->kind))
            continue;
          uint_t ni = g->var2node[vi];
          uint_t nj = g->var2node[vj];
          assert (ni < g->nodes_size);
          assert (nj < g->nodes_size);
          if (ni == nj)
            {
              noll_dform_t *df =
                noll_dform_new_eq (noll_dterm_new_var (vi, ty_vi->kind),
                                   noll_dterm_new_var (vj,
                                                       ty_vj->kind));
              noll_dform_array_push (res, df);
            }
          // no difference constraints in the logic of msets
          if ((ty_vi->kind == NOLL_TYP_INT)
              && (noll_graph_is_diff (g, ni, nj) == true))
            {
              noll_dform_t *df =
                noll_dform_new_eq (noll_dterm_new_var (vi, ty_vi->kind),
                                   noll_dterm_new_var (vj,
                                                       ty_vj->kind));
              df->kind = NOLL_DATA_NEQ;
              noll_dform_array_push (res, df);
            }
        }
    }
  g->isDataComplete = true;
}
示例#3
0
noll_dform_t *
noll_dform_apply (noll_dform_t * df, noll_uid_array * m)
{
  if (df == NULL)
    return NULL;
  /// if m == NULL, copy only
  noll_dform_t *res = noll_dform_new ();
  res->kind = df->kind;
  res->typ = df->typ;
  if (df->kind == NOLL_DATA_IMPLIES)
    {
      res->p.bargs = noll_dform_array_new ();
      noll_dform_array_reserve (res->p.bargs, 2);
      for (uint_t i = 0; i < 2; i++)
        {
          noll_dform_t *a =
            noll_dform_apply (noll_vector_at (df->p.bargs, i), m);
          if (a == NULL)
            {
              noll_dform_free (res);
              return NULL;
            }
          noll_dform_array_push (res->p.bargs, a);
        }
      return res;
    }
  /// only dterm arguments
  if (df->p.targs != NULL)
    {
      uint_t size = noll_vector_size (df->p.targs);
      res->p.targs = noll_dterm_array_new ();
      noll_dterm_array_reserve (res->p.targs, size);
      for (uint_t i = 0; i < size; i++)
        {
          noll_dterm_t *a =
            noll_dterm_apply (noll_vector_at (df->p.targs, i), m);
          if (a == NULL)
            {
              noll_dform_free (res);
              return NULL;
            }
          noll_dterm_array_push (res->p.targs, a);
        }
    }
  return res;
}
示例#4
0
/**
 * @brief Apply the substitution @p m on @p df and generate new formulas 
 */
noll_dform_array *
noll_dform_array_apply (noll_dform_array * df, noll_uid_array * m)
{
  if (df == NULL || m == NULL)
    return NULL;
  noll_dform_array *res = noll_dform_array_new ();
  for (uint_t i = 0; i < noll_vector_size (df); i++)
    {
      noll_dform_t *dfi = noll_vector_at (df, i);
      noll_dform_t *dfi_m = noll_dform_apply (dfi, m);
      if (dfi_m == NULL)
        {
          noll_dform_array_delete (res);
          return NULL;
        }
      noll_dform_array_push (res, dfi_m);
    }
  return res;
}
示例#5
0
/**
 * @brief Check that @p diff entails @p f->m[@p m].
 * 
 * @return 0 if some constraint not entailed, 1 otherwise
 */
int
noll_pure_check_entl (bool ** diff, uint_t dsize, noll_pure_t * f,
                      noll_uid_array * lmap,
                      noll_var_array * exvars, noll_uid_array * map,
                      noll_dform_array * df)
{
  /// this procedure could also be called for the pure part
  /// of a recursive rule, where @p f->m includes also existential vars,
  /// all shall be included in @p m 
  assert (noll_vector_size (exvars) == noll_vector_size (map));
  assert (f->size == noll_vector_size (lmap));
  noll_dform_array *dfn = noll_dform_array_new ();
  int res = 1;
  for (uint_t lv2 = 1; (lv2 < noll_vector_size (lmap)) && res; lv2++)
    {
      uint_t v2 = noll_vector_at (lmap, lv2);
      noll_type_t *ty2 = noll_var_type (exvars, v2);
      for (uint_t lv1 = 0; (lv1 < lv2) && res; lv1++)
        {
          uint_t v1 = noll_vector_at (lmap, lv1);
          noll_type_t *ty1 = noll_var_type (exvars, v1);
          noll_pure_op_t rhs_op = noll_pure_matrix_at (f, lv1, lv2);
          if (rhs_op == NOLL_PURE_OTHER)
            continue;
          uint_t nv1 = noll_vector_at (map, v1);
          uint_t nv2 = noll_vector_at (map, v2);
          if (rhs_op == NOLL_PURE_EQ)
            {
              if (ty1->kind != ty2->kind)
                {
#ifndef NDEBUG
                  fprintf (stdout,
                           "\n**** pure_check_entl: fails (typing) to prove (n%d == n%d)\n",
                           nv1, nv2);
#endif
                  res = 0;
                }
              else
                /// one or both of variables is not yet bounded to a node, 
                /// update m if the other is bounded
              if (nv1 < dsize && nv2 >= dsize)
                noll_uid_array_set (map, v2, nv1);
              else if (nv2 < dsize && nv1 >= dsize)
                noll_uid_array_set (map, v1, nv2);
              else if (ty1->kind == NOLL_TYP_RECORD)
                {
                  /// shall be equal and less than dsize
                  res = ((nv1 < dsize) && (nv2 < dsize)
                         && (nv1 == nv2)) ? 1 : 0;
#ifndef NDEBUG
                  if (res == 0)
                    fprintf (stdout,
                             "\n**** pure_check_entl: fails (record) to prove (n%d == n%d)\n",
                             nv1, nv2);
#endif

                }
              else
                {
                  /// there are nodes for data variables, generate a data constraint

                  noll_dform_t *df_eq =
                    noll_dform_new_eq (noll_dterm_new_var (v1, ty1->kind),
                                       noll_dterm_new_var (v2,
                                                           ty2->kind));
                  noll_dform_array_push (dfn, df_eq);
                }
            }
          else if ((nv1 < dsize) && (nv2 < dsize))
            {
              assert (rhs_op == NOLL_PURE_NEQ);
              bool lhs_isDiff = (nv1 != nv2);
              if (nv1 < nv2)
                lhs_isDiff = diff[nv2][nv1];
              else if (nv2 < nv1)
                lhs_isDiff = diff[nv1][nv2];
              res = (lhs_isDiff) ? 1 : 0;
            }
          else
            {
              /// inequality between unmapped vars
              /// push the constraint if vars are integer vars
              if ((ty1->kind == ty2->kind) && (ty1->kind == NOLL_TYP_INT))
                /// generate an inequality constraint for data vars
                {
                  noll_dform_t *df_eq =
                    noll_dform_new_eq (noll_dterm_new_var (v1, ty1->kind),
                                       noll_dterm_new_var (v2,
                                                           ty2->kind));
                  df_eq->kind = NOLL_DATA_NEQ;
                  noll_dform_array_push (dfn, df_eq);
                }
              else
                /// cannot be checked
                assert (0);
            }
        }
    }
  if (res == 1)
    noll_dform_array_cup_all (df, dfn);
  noll_dform_array_clear (dfn);
  return res;
}