/** * Build a formula from the matrix of the predicate. * Unfolds one time the matrix. * @param pid predicate identifier * @param args predicate actual argument * @result a formula which contains the matrix of the predicate * instantiated with the actual arguments */ noll_form_t * noll_pred_get_matrix1 (uid_t pid) { const noll_pred_t *pred = noll_pred_getpred (pid); assert (pred != NULL); /* pred->def->vars is an array built from * - nil (at entry 0 of the array) * - args (starting at entry 1 until pred->def->fargs * - existentially quantified variables */ /* Build and empty formula */ noll_form_t *res = noll_form_new (); res->kind = NOLL_FORM_SAT; noll_var_array_copy (res->lvars, pred->def->vars); // copy all from vars /* TODO: use svars for nested predicate calls */ res->svars = noll_var_array_new (); // Warning: do not use NULL res->share = noll_share_array_new (); // Warning: do not use NULL /* - build the pure part E != {F} U B */ res->pure = noll_pure_new (noll_vector_size (pred->def->vars)); noll_form_add_neq (res, 1, 0); for (size_t i = 2; i < noll_vector_size (pred->def->vars); i++) noll_form_add_neq (res, 1, i); /* - build the spatial part */ if (pred->def->sigma_1 == NULL) res->space = pred->def->sigma_0; // TODO: make a copy else { res->space = noll_space_new (); res->space->kind = NOLL_SPACE_SSEP; if (pred->def->sigma_1->kind == NOLL_SPACE_SSEP) { /* TODO: deal with loop */ noll_space_array_copy (res->space->m.sep, pred->def->sigma_1->m.sep); noll_space_array_push (res->space->m.sep, pred->def->sigma_0); } else { res->space->m.sep = noll_space_array_new (); noll_space_array_push (res->space->m.sep, pred->def->sigma_0); /* TODO: deal with loop */ noll_space_array_push (res->space->m.sep, pred->def->sigma_1); } } /* substitute formal arguments with actual arguments */ #ifndef NDEBUG fprintf (stderr, "\n- matrix formula \n"); noll_form_fprint (stderr, res); fflush (stderr); #endif return res; }
/** * Build a formula from the matrix of the predicate. * Unfolds two times the matrix. * @param pid predicate identifier * @param args predicate actual argument * @result a formula which contains the matrix of the predicate * instantiated with the actual arguments */ noll_form_t * noll_pred_get_matrix (uid_t pid) { const noll_pred_t *pred = noll_pred_getpred (pid); assert (pred != NULL); /* pred->def->vars is an array built from * - nil (at entry 0 of the array) * - args (starting at entry 1 until pred->def->fargs * - existentially quantified variables */ /* Build and empty formula */ noll_form_t *res = noll_form_new (); res->kind = NOLL_FORM_SAT; /* copy all from vars */ noll_var_array_copy (res->lvars, pred->def->vars); /* insert a copy of existential variables from X_tl+1 ... */ for (size_t i = pred->def->fargs + 2; i < noll_vector_size (pred->def->vars); i++) { noll_var_t *vi = noll_vector_at (pred->def->vars, i); noll_var_t *vip = noll_var_copy (vi); /* change the name by adding a p suffix */ size_t nlen = strlen (vi->vname) + 2; // p and \O vip->vname = (char *) realloc (vip->vname, nlen * sizeof (char)); snprintf (vip->vname, nlen, "%sp", vi->vname); vip->vid = noll_vector_size (pred->def->vars) + i - pred->def->fargs - 2; noll_var_array_push (res->lvars, vip); } #ifndef NDEBUG fprintf (stderr, "\n- new list of variables \n"); noll_var_array_fprint (stderr, res->lvars, ", "); fflush (stderr); #endif /* TODO: use svars for nested predicate calls */ res->svars = noll_var_array_new (); // Warning: do not use NULL res->share = noll_share_array_new (); // Warning: do not use NULL /* - build the pure part * E != {NULL, F} U B * X_tl != {NULL, F} U B * TODO: E != X_tl is computed by normalisation */ res->pure = noll_pure_new (noll_vector_size (res->lvars)); uid_t id_in = 1; uid_t id_x_tl = pred->def->fargs + 1; /* E != NULL, X_tl != NULL */ noll_form_add_neq (res, id_in, 0); noll_form_add_neq (res, id_x_tl, 0); /* E != X_tl */ noll_form_add_neq (res, id_x_tl, id_in); for (uid_t i = 1; i < pred->def->fargs; i++) { /* args in res->lvars are shifted by 1 to introduce NULL */ noll_form_add_neq (res, id_in, i + 1); noll_form_add_neq (res, id_x_tl, i + 1); } /* - build the spatial part */ uint_t res_size = 0; res->space = noll_space_new (); res->space->kind = NOLL_SPACE_SSEP; res->space->m.sep = noll_space_array_new (); /* + push the first unfolding */ noll_space_array_push (res->space->m.sep, pred->def->sigma_0); // TODO: make a copy res_size++; if (pred->def->sigma_1 != NULL) { if (pred->def->sigma_1->kind == NOLL_SPACE_SSEP) { /* TODO: unfold the loop construct */ for (uint_t i = 0; i < noll_vector_size (pred->def->sigma_1->m.sep); i++) { noll_space_array_push (res->space->m.sep, noll_vector_at (pred->def->sigma_1->m. sep, i)); res_size++; } } else { /* TODO: unfold the loop construct */ noll_space_array_push (res->space->m.sep, pred->def->sigma_1); res_size++; } } /* + push the second unfolding and substitute existentials by new vars */ noll_uid_array *alpha = noll_uid_array_new (); noll_uid_array_push (alpha, 0); // null unchanged noll_uid_array_push (alpha, id_x_tl); // E is replaced by X_tl for (uid_t i = 1; i < pred->def->fargs; i++) noll_uid_array_push (alpha, i + 1); // args are unchanged noll_uid_array_push (alpha, 2); // X_tl is replaced by F /* the newly introduced vars replace the old ones */ for (uid_t i = pred->def->fargs + 2; i < noll_vector_size (pred->def->vars); i++) { /* new existential variables substitute ones in the definition */ noll_uid_array_push (alpha, noll_vector_size (pred->def->vars) + i - pred->def->fargs - 2); } #ifndef NDEBUG fprintf (stderr, "\n- substitution: "); for (uid_t i = 0; i < noll_vector_size (alpha); i++) fprintf (stderr, "%s -> %s, ", noll_var_name (res->lvars, i, NOLL_TYP_RECORD), noll_var_name (res->lvars, noll_vector_at (alpha, i), NOLL_TYP_RECORD)); fprintf (stderr, "\n"); fflush (stderr); #endif for (uint_t j = 0; j < res_size; j++) { noll_space_t *sj = noll_vector_at (res->space->m.sep, j); noll_space_t *sj_sub = noll_space_sub (sj, alpha); #ifndef NDEBUG fprintf (stderr, "\n\tsub-%d formula \n", j); noll_space_fprint (stderr, res->lvars, NULL, sj_sub); fflush (stderr); #endif noll_space_array_push (res->space->m.sep, sj_sub); } /* free allocated memory */ noll_uid_array_delete (alpha); #ifndef NDEBUG fprintf (stderr, "\n- matrix formula \n"); noll_form_fprint (stderr, res); fflush (stderr); #endif return res; }
/** * Allocate a graph using the informations about the formula. * If nodes==0 or edges==0, return the empty graph, i.e., * only nil node. */ noll_graph_t * noll_graph_alloc (noll_var_array * lvars, noll_var_array * svars, uint_t nodes, uint_t edges, uint_t * vars) { noll_graph_t *res = (noll_graph_t *) malloc (sizeof (noll_graph_t)); #ifndef NDEBUG noll_var_array_fprint (stdout, lvars, "Vars of the graph: "); #endif res->lvars = noll_var_array_new (); noll_var_array_copy (res->lvars, lvars); res->svars = noll_var_array_new (); noll_var_array_copy (res->svars, svars); // size of the adj matrices res->nodes_size = nodes; /* * labeling of nodes by variables: fill mapping var2nodes */ if (!vars) { res->var2node = (uint_t *) malloc (noll_vector_size (lvars) * sizeof (uint_t)); for (uint_t i = 0; i < noll_vector_size (lvars); i++) res->var2node[i] = UNDEFINED_ID; } else res->var2node = vars; /* * allocate the array of edges */ res->edges = noll_edge_array_new (); if (edges > 0) noll_edge_array_reserve (res->edges, edges); /* * allocate the adjacency matrices */ res->mat = (noll_uid_array **) malloc (res->nodes_size * sizeof (noll_uid_array *)); res->rmat = (noll_uid_array **) malloc (res->nodes_size * sizeof (noll_uid_array *)); for (uint_t i = 0; i < res->nodes_size; i++) { res->mat[i] = NULL; res->rmat[i] = NULL; } /* * allocate the difference edges, a low-diagonal matrix */ res->diff = (bool **) malloc (res->nodes_size * sizeof (bool *)); for (uint_t i = 0; i < res->nodes_size; i++) { res->diff[i] = (bool *) malloc ((i + 1) * sizeof (bool)); for (uint_t j = 0; j <= i; j++) res->diff[i][j] = false; } res->data = NULL; res->isDataComplete = false; /* * allocate the mapping of set variables to edges */ res->sloc2edge = (uint_t *) malloc (noll_vector_size (svars) * sizeof (uint_t)); for (uint_t i = 0; i < noll_vector_size (svars); i++) { res->sloc2edge[i] = UNDEFINED_ID; } // allocate the sharing array res->share = noll_share_array_new (); res->isComplete = false; return res; }
noll_share_array * noll_share_new () { return noll_share_array_new (); }