Skip to content

Commit feb9fe1

Browse files
committed
Feature: add LAGraph_rule_EWCNF
1 parent b13a244 commit feb9fe1

File tree

3 files changed

+196
-87
lines changed

3 files changed

+196
-87
lines changed

experimental/algorithm/LAGraph_CFL_reachability_advanced.c

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@
131131
} \
132132
}
133133

134-
// LAGraph_CFL_reachability: Context-Free Language Reachability Matrix-Based Algorithm
134+
// LAGraph_CFL_reachability_adv: Context-Free Language Reachability Matrix-Based Algorithm
135135
//
136136
// This function determines the set of vertex pairs (u, v) in a graph (represented by
137137
// adjacency matrices) such that there is a path from u to v, where the edge labels
@@ -176,25 +176,35 @@
176176
GrB_Info LAGraph_CFL_reachability_adv(
177177
// Output
178178
GrB_Matrix *outputs, // Array of matrices containing results.
179-
// The size of the array must be equal to nonterms_count.
179+
// The size of the array must be equal to the count
180+
// of symbols (symbols_amount).
180181
//
181182
// outputs[k]: (i, j) = true if and only if there is a path
182183
// from node i to node j whose edge labels form a word
183-
// derivable from the non-terminal 'k' of the specified CFG.
184+
// derivable from the symbol 'k' of the specified CFG.
185+
//
186+
// Note: output[t] where t is index of terminal will be just full
187+
// copy of adj_matrices[t]
184188
// Input
185-
const GrB_Matrix *adj_matrices, // Array of adjacency matrices representing the graph.
186-
// The length of this array is equal to the count of
187-
// terminals (terms_count).
188-
//
189-
// adj_matrices[t]: (i, j) == 1 if and only if there
190-
// is an edge between nodes i and j with the label of
191-
// the terminal corresponding to index 't' (where t is
192-
// in the range [0, terms_count - 1]).
193-
size_t symbols_amount,
194-
const LAGraph_rule_WCNF *rules, // The rules of the CFG.
195-
size_t rules_count, // The total number of rules in the CFG.
196-
char *msg, // Message string for error reporting.
197-
int8_t optimizations // Optimizations flags
189+
const GrB_Matrix
190+
*adj_matrices, // Array of adjacency matrices representing the graph.
191+
// The length of this array is equal to the count of
192+
// symbols (symbols_amount).
193+
//
194+
// adj_matrices[i]: (i, j) == 1 if and only if there
195+
// is an edge between nodes i and j with the label of
196+
// the symbol corresponding to index 'i' (where i is
197+
// in the range [0, symbols_amount - 1]).
198+
//
199+
// Note: adj_matrices[N] where N is index of nonterminal doesn't
200+
// used for algorithms and may be NULL
201+
size_t symbols_amount, // Count of terminal and nonterminals
202+
const LAGraph_rule_EWCNF *rules, // The rules of the CFG.
203+
// Warning: now not ready for N -> A rules, where is
204+
// N and A are nonterminals.
205+
size_t rules_count, // The total number of rules in the CFG.
206+
char *msg, // Message string for error reporting.
207+
int8_t optimizations // Optimizations flags
198208
) {
199209
// Declare workspace and clear the msg string, if not NULL
200210
CFL_Matrix *delta_matrices, *matrices, *temp_matrices;
@@ -242,7 +252,7 @@ GrB_Info LAGraph_CFL_reachability_adv(
242252
GrB_Index n;
243253
GRB_TRY(GrB_Matrix_ncols(&n, adj_matrices[0]));
244254

245-
// Create nonterms matrices
255+
// Create symbol matrices
246256
for (size_t i = 0; i < symbols_amount; i++) {
247257

248258
GrB_Index nrows;
@@ -278,7 +288,7 @@ GrB_Info LAGraph_CFL_reachability_adv(
278288
rule_error_s nonterm_err = {0};
279289
rule_error_s invalid_err = {0};
280290
for (size_t i = 0; i < rules_count; i++) {
281-
LAGraph_rule_WCNF rule = rules[i];
291+
LAGraph_rule_EWCNF rule = rules[i];
282292

283293
bool is_rule_eps = rule.prod_A == -1 && rule.prod_B == -1;
284294
bool is_rule_term = rule.prod_A != -1 && rule.prod_B == -1;
@@ -346,7 +356,7 @@ GrB_Info LAGraph_CFL_reachability_adv(
346356

347357
// Rule [Variable -> term]
348358
for (size_t i = 0; i < term_rules_count; i++) {
349-
LAGraph_rule_WCNF term_rule = rules[term_rules[i]];
359+
LAGraph_rule_EWCNF term_rule = rules[term_rules[i]];
350360
CFL_Matrix *nonterm_matrix = &delta_matrices[term_rule.nonterm];
351361
CFL_Matrix *term_matrix = &delta_matrices[term_rule.prod_A];
352362

@@ -368,7 +378,7 @@ GrB_Info LAGraph_CFL_reachability_adv(
368378

369379
// Rule [Variable -> eps]
370380
for (size_t i = 0; i < eps_rules_count; i++) {
371-
LAGraph_rule_WCNF eps_rule = rules[eps_rules[i]];
381+
LAGraph_rule_EWCNF eps_rule = rules[eps_rules[i]];
372382

373383
CFL_Matrix *nonterm_matrix = &delta_matrices[eps_rule.nonterm];
374384

@@ -406,7 +416,7 @@ GrB_Info LAGraph_CFL_reachability_adv(
406416

407417
TIMER_START();
408418
for (size_t i = 0; i < bin_rules_count; i++) {
409-
LAGraph_rule_WCNF bin_rule = rules[bin_rules[i]];
419+
LAGraph_rule_EWCNF bin_rule = rules[bin_rules[i]];
410420
CFL_Matrix *A = &matrices[bin_rule.prod_A];
411421
CFL_Matrix *B = &delta_matrices[bin_rule.prod_B];
412422
CFL_Matrix *C = &temp_matrices[bin_rule.nonterm];
@@ -441,7 +451,7 @@ GrB_Info LAGraph_CFL_reachability_adv(
441451

442452
TIMER_START()
443453
for (size_t i = 0; i < bin_rules_count; i++) {
444-
LAGraph_rule_WCNF bin_rule = rules[bin_rules[i]];
454+
LAGraph_rule_EWCNF bin_rule = rules[bin_rules[i]];
445455
CFL_Matrix *A = &matrices[bin_rule.prod_B];
446456
CFL_Matrix *B = &delta_matrices[bin_rule.prod_A];
447457
CFL_Matrix *C = &temp_matrices[bin_rule.nonterm];
@@ -460,7 +470,7 @@ GrB_Info LAGraph_CFL_reachability_adv(
460470

461471
// Rule [Variable -> term]
462472
for (size_t i = 0; i < term_rules_count; i++) {
463-
LAGraph_rule_WCNF term_rule = rules[term_rules[i]];
473+
LAGraph_rule_EWCNF term_rule = rules[term_rules[i]];
464474
CFL_Matrix *A = &temp_matrices[term_rule.nonterm];
465475
CFL_Matrix *B = &delta_matrices[term_rule.prod_A];
466476

experimental/test/test_CFL_reachability_adv.c

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ typedef struct {
4141
size_t nonterms_count;
4242
size_t terms_count;
4343
size_t rules_count;
44-
LAGraph_rule_WCNF *rules;
44+
LAGraph_rule_EWCNF *rules;
4545
} grammar_t;
4646

4747
GrB_Matrix *adj_matrices = NULL;
@@ -124,14 +124,14 @@ void free_workspace() {
124124
// A -> a [1 4 -1 0]
125125
// B -> b [2 5 -1 0]
126126
void init_grammar_aSb() {
127-
LAGraph_rule_WCNF *rules = NULL;
128-
LAGraph_Calloc((void **)&rules, 5, sizeof(LAGraph_rule_WCNF), msg);
127+
LAGraph_rule_EWCNF *rules = NULL;
128+
LAGraph_Calloc((void **)&rules, 5, sizeof(LAGraph_rule_EWCNF), msg);
129129

130-
rules[0] = (LAGraph_rule_WCNF){0, 1, 2, 0};
131-
rules[1] = (LAGraph_rule_WCNF){0, 1, 3, 0};
132-
rules[2] = (LAGraph_rule_WCNF){3, 0, 2, 0};
133-
rules[3] = (LAGraph_rule_WCNF){1, 4, -1, 0};
134-
rules[4] = (LAGraph_rule_WCNF){2, 5, -1, 0};
130+
rules[0] = (LAGraph_rule_EWCNF){0, 1, 2, 0, 0};
131+
rules[1] = (LAGraph_rule_EWCNF){0, 1, 3, 0, 0};
132+
rules[2] = (LAGraph_rule_EWCNF){3, 0, 2, 0, 0};
133+
rules[3] = (LAGraph_rule_EWCNF){1, 4, -1, 0, 0};
134+
rules[4] = (LAGraph_rule_EWCNF){2, 5, -1, 0, 0};
135135

136136
grammar = (grammar_t){
137137
.nonterms_count = 4, .terms_count = 2, .rules_count = 5, .rules = rules};
@@ -145,12 +145,12 @@ void init_grammar_aSb() {
145145
// S -> a [0 1 -1 0]
146146
// S -> eps [0 -1 -1 0]
147147
void init_grammar_aS() {
148-
LAGraph_rule_WCNF *rules = NULL;
149-
LAGraph_Calloc((void **)&rules, 3, sizeof(LAGraph_rule_WCNF), msg);
148+
LAGraph_rule_EWCNF *rules = NULL;
149+
LAGraph_Calloc((void **)&rules, 3, sizeof(LAGraph_rule_EWCNF), msg);
150150

151-
rules[0] = (LAGraph_rule_WCNF){0, 0, 0, 0};
152-
rules[1] = (LAGraph_rule_WCNF){0, 1, -1, 0};
153-
rules[2] = (LAGraph_rule_WCNF){0, -1, -1, 0};
151+
rules[0] = (LAGraph_rule_EWCNF){0, 0, 0, 0};
152+
rules[1] = (LAGraph_rule_EWCNF){0, 1, -1, 0};
153+
rules[2] = (LAGraph_rule_EWCNF){0, -1, -1, 0};
154154

155155
grammar = (grammar_t){
156156
.nonterms_count = 1, .terms_count = 1, .rules_count = 3, .rules = rules};
@@ -188,35 +188,35 @@ void init_grammar_aS() {
188188
// S23 -> b [23 26 -1 0]
189189
// S24 -> b [24 26 -1 0]
190190
void init_grammar_complex() {
191-
LAGraph_rule_WCNF *rules = NULL;
192-
LAGraph_Calloc((void **)&rules, 26, sizeof(LAGraph_rule_WCNF), msg);
193-
194-
rules[0] = (LAGraph_rule_WCNF){0, 1, 2, 0};
195-
rules[1] = (LAGraph_rule_WCNF){0, 15, 16, 0};
196-
rules[2] = (LAGraph_rule_WCNF){1, 3, 4, 0};
197-
rules[3] = (LAGraph_rule_WCNF){2, 5, 6, 0};
198-
rules[4] = (LAGraph_rule_WCNF){3, 7, 8, 0};
199-
rules[5] = (LAGraph_rule_WCNF){4, 9, 10, 0};
200-
rules[6] = (LAGraph_rule_WCNF){5, 11, 12, 0};
201-
rules[7] = (LAGraph_rule_WCNF){6, 13, 14, 0};
202-
rules[8] = (LAGraph_rule_WCNF){16, 17, 18, 0};
203-
rules[9] = (LAGraph_rule_WCNF){17, 19, 20, 0};
204-
rules[10] = (LAGraph_rule_WCNF){18, 21, 22, 0};
205-
rules[11] = (LAGraph_rule_WCNF){22, 23, 24, 0};
206-
rules[12] = (LAGraph_rule_WCNF){7, 25, -1, 0};
207-
rules[13] = (LAGraph_rule_WCNF){8, 25, -1, 0};
208-
rules[14] = (LAGraph_rule_WCNF){9, 25, -1, 0};
209-
rules[15] = (LAGraph_rule_WCNF){10, 25, -1, 0};
210-
rules[16] = (LAGraph_rule_WCNF){11, 26, -1, 0};
211-
rules[17] = (LAGraph_rule_WCNF){12, 26, -1, 0};
212-
rules[18] = (LAGraph_rule_WCNF){13, 26, -1, 0};
213-
rules[19] = (LAGraph_rule_WCNF){14, 26, -1, 0};
214-
rules[20] = (LAGraph_rule_WCNF){15, 25, -1, 0};
215-
rules[21] = (LAGraph_rule_WCNF){19, 25, -1, 0};
216-
rules[22] = (LAGraph_rule_WCNF){20, 25, -1, 0};
217-
rules[23] = (LAGraph_rule_WCNF){21, 26, -1, 0};
218-
rules[24] = (LAGraph_rule_WCNF){23, 26, -1, 0};
219-
rules[25] = (LAGraph_rule_WCNF){24, 26, -1, 0};
191+
LAGraph_rule_EWCNF *rules = NULL;
192+
LAGraph_Calloc((void **)&rules, 26, sizeof(LAGraph_rule_EWCNF), msg);
193+
194+
rules[0] = (LAGraph_rule_EWCNF){0, 1, 2, 0, 0};
195+
rules[1] = (LAGraph_rule_EWCNF){0, 15, 16, 0, 0};
196+
rules[2] = (LAGraph_rule_EWCNF){1, 3, 4, 0, 0};
197+
rules[3] = (LAGraph_rule_EWCNF){2, 5, 6, 0, 0};
198+
rules[4] = (LAGraph_rule_EWCNF){3, 7, 8, 0, 0};
199+
rules[5] = (LAGraph_rule_EWCNF){4, 9, 10, 0, 0};
200+
rules[6] = (LAGraph_rule_EWCNF){5, 11, 12, 0, 0};
201+
rules[7] = (LAGraph_rule_EWCNF){6, 13, 14, 0, 0};
202+
rules[8] = (LAGraph_rule_EWCNF){16, 17, 18, 0, 0};
203+
rules[9] = (LAGraph_rule_EWCNF){17, 19, 20, 0, 0};
204+
rules[10] = (LAGraph_rule_EWCNF){18, 21, 22, 0, 0};
205+
rules[11] = (LAGraph_rule_EWCNF){22, 23, 24, 0, 0};
206+
rules[12] = (LAGraph_rule_EWCNF){7, 25, -1, 0, 0};
207+
rules[13] = (LAGraph_rule_EWCNF){8, 25, -1, 0, 0};
208+
rules[14] = (LAGraph_rule_EWCNF){9, 25, -1, 0, 0};
209+
rules[15] = (LAGraph_rule_EWCNF){10, 25, -1, 0, 0};
210+
rules[16] = (LAGraph_rule_EWCNF){11, 26, -1, 0, 0};
211+
rules[17] = (LAGraph_rule_EWCNF){12, 26, -1, 0, 0};
212+
rules[18] = (LAGraph_rule_EWCNF){13, 26, -1, 0, 0};
213+
rules[19] = (LAGraph_rule_EWCNF){14, 26, -1, 0, 0};
214+
rules[20] = (LAGraph_rule_EWCNF){15, 25, -1, 0, 0};
215+
rules[21] = (LAGraph_rule_EWCNF){19, 25, -1, 0, 0};
216+
rules[22] = (LAGraph_rule_EWCNF){20, 25, -1, 0, 0};
217+
rules[23] = (LAGraph_rule_EWCNF){21, 26, -1, 0, 0};
218+
rules[24] = (LAGraph_rule_EWCNF){23, 26, -1, 0, 0};
219+
rules[25] = (LAGraph_rule_EWCNF){24, 26, -1, 0, 0};
220220

221221
grammar = (grammar_t){
222222
.nonterms_count = 25, .terms_count = 2, .rules_count = 26, .rules = rules};
@@ -663,27 +663,27 @@ void test_CFL_reachability_invalid_rules(void) {
663663

664664
// Rule [Variable -> _ B]
665665
grammar.rules[0] =
666-
(LAGraph_rule_WCNF){.nonterm = 0, .prod_A = -1, .prod_B = 1, .index = 0};
666+
(LAGraph_rule_EWCNF){.nonterm = 0, .prod_A = -1, .prod_B = 1, .indexed_count = 0};
667667
check_error(GrB_INVALID_VALUE, 0);
668668

669669
// Rule [_ -> A B]
670670
grammar.rules[0] =
671-
(LAGraph_rule_WCNF){.nonterm = -1, .prod_A = 1, .prod_B = 2, .index = 0};
671+
(LAGraph_rule_EWCNF){.nonterm = -1, .prod_A = 1, .prod_B = 2, .indexed_count = 0};
672672
check_error(GrB_INVALID_VALUE, 0);
673673

674674
// Rule [C -> A B], where C >= nonterms_count
675675
grammar.rules[0] =
676-
(LAGraph_rule_WCNF){.nonterm = 10, .prod_A = 1, .prod_B = 2, .index = 0};
676+
(LAGraph_rule_EWCNF){.nonterm = 10, .prod_A = 1, .prod_B = 2, .indexed_count = 0};
677677
check_error(GrB_INVALID_VALUE, 0);
678678

679679
// Rule [S -> A B], where A >= nonterms_count
680680
grammar.rules[0] =
681-
(LAGraph_rule_WCNF){.nonterm = 0, .prod_A = 10, .prod_B = 2, .index = 0};
681+
(LAGraph_rule_EWCNF){.nonterm = 0, .prod_A = 10, .prod_B = 2, .indexed_count = 0};
682682
check_error(GrB_INVALID_VALUE, 0);
683683

684684
// Rule [C -> t], where t >= terms_count
685-
grammar.rules[0] =
686-
(LAGraph_rule_WCNF){.nonterm = 0, .prod_A = 10, .prod_B = -1, .index = 0};
685+
grammar.rules[0] = (LAGraph_rule_EWCNF){
686+
.nonterm = 0, .prod_A = 10, .prod_B = -1, .indexed_count = 0};
687687
check_error(GrB_INVALID_VALUE, 0);
688688

689689
free_workspace();

0 commit comments

Comments
 (0)