replaced tabs with whitespace, linted c code, reduced line lengths if possible for better readability

This commit is contained in:
Ämin Baumeler 2023-09-07 13:36:33 +02:00
parent ab5a90dc38
commit 642b78c900
4 changed files with 935 additions and 826 deletions

View File

@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: 2023 Ämin Baumeler <amin@indyfac.ch> and Eleftherios-Ermis Tselentis <eleftheriosermis.tselentis@oeaw.ac.at> // SPDX-FileCopyrightText: 2023 Ämin Baumeler <amin@indyfac.ch> and
// Eleftherios-Ermis Tselentis <eleftheriosermis.tselentis@oeaw.ac.at>
// //
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
@ -8,10 +9,10 @@
/*** /***
* Read graphs from file. * Read graphs from file.
* Input `filename': string * Input `filename': string
* Input `cnt': pointer to int * Input `cnt': pointer to int
* Input `maxdim': pointer to int * Input `maxdim': pointer to int
* Output: pointer to graph data * Output: pointer to graph data
* *
* This function sets `cnt' to the total number of graphs read from `filename', * This function sets `cnt' to the total number of graphs read from `filename',
* sets `maxdim' to the dimension (number of nodes) of the largest graph, * sets `maxdim' to the dimension (number of nodes) of the largest graph,
@ -20,93 +21,96 @@
* The ith graph is at position i*(maxdim*maxdim + 1). * The ith graph is at position i*(maxdim*maxdim + 1).
***/ ***/
int* read_graphs(char* filename, int *cnt, int *maxdim) { int* read_graphs(char* filename, int *cnt, int *maxdim) {
// Open file // Open file
FILE *fp; FILE *fp;
fp = fopen(filename, "r"); fp = fopen(filename, "r");
if(fp == NULL) if (fp == NULL)
return NULL; return NULL;
// Count number of lines, allocate space and initiate counter // Count number of lines, allocate space and initiate counter
char ch; char ch;
int n = 0; int n = 0;
*cnt = 0; // Total number of graphs *cnt = 0; // Total number of graphs
*maxdim = 0; // Maximum number of vertices *maxdim = 0; // Maximum number of vertices
while(!feof(fp)) { while (!feof(fp)) {
ch = fgetc(fp); ch = fgetc(fp);
switch(ch) { switch (ch) {
case '\n': case '\n':
(*cnt)++; (*cnt)++;
n = 0; n = 0;
break; break;
case '{': case '{':
case '}': case '}':
*maxdim = (n > *maxdim) ? n : *maxdim; *maxdim = (n > *maxdim) ? n : *maxdim;
n = 0; n = 0;
break; break;
case '0': case '0':
case '1': case '1':
n++; n++;
break; break;
case ',': case ',':
case ' ': case ' ':
case 0xffffffff: case 0xffffffff:
break; break;
default: default:
return NULL; // Format error return NULL; // Format error
} }
} }
rewind(fp); // Return to start of file rewind(fp); // Return to start of file
// Allocate space for graph data // Allocate space for graph data
const int gdatasize = *maxdim * *maxdim + 1; // Size allocation per graph // Size allocation per graph
const int arraysize = (1+ *cnt) * gdatasize; // Total space to allocate const int gdatasize = *maxdim * *maxdim + 1;
int *graphs = (int*)malloc(sizeof(int)*arraysize); // Allocation // Total space to allocate
if(!graphs) { const int arraysize = (1+ *cnt) * gdatasize;
fprintf(stderr, "ERROR: Could not allocate enough memory to store the graphs.\n"); // Allocation
return NULL; int *graphs = (int*)malloc(sizeof(int)*arraysize);
} if (!graphs) {
// Parse file fprintf(stderr, "ERROR: Could not allocate enough memory to store the graphs.\n");
int col = 0; // Column number return NULL;
int row = 0; // Row number }
int i = 0; // Current graph index // Parse file
n = -1; // Graph dimension int col = 0; // Column number
int j = 0; // Running index int row = 0; // Row number
while ((ch = fgetc(fp)) != EOF) { int i = 0; // Current graph index
// New line encountered n = -1; // Graph dimension
if(ch == '\n') { int j = 0; // Running index
if(row != n) { while ((ch = fgetc(fp)) != EOF) {
fprintf(stderr, "ERROR: File not properly formatted.\n"); // New line encountered
return NULL; if (ch == '\n') {
} if (row != n) {
graphs[i*gdatasize] = n; fprintf(stderr, "ERROR: File not properly formatted.\n");
i++; return NULL;
j = 0; }
col = 0; graphs[i*gdatasize] = n;
row = 0; i++;
n = -1; j = 0;
// Matrix entry encountered col = 0;
} else if(ch == '0' || ch == '1') { row = 0;
int x = ch - '0'; n = -1;
graphs[i*gdatasize + 1 + j] = x; // Matrix entry encountered
col++; } else if (ch == '0' || ch == '1') {
j++; int x = ch - '0';
// End-of-row or end-of-matrix encountered graphs[i*gdatasize + 1 + j] = x;
} else if(ch == '}') { col++;
if(n == -1) { j++;
n = col; // End-of-row or end-of-matrix encountered
} else if(col > 0 && n != col) { } else if (ch == '}') {
fprintf(stderr, "ERROR: File not properly formatted.\n"); if (n == -1) {
return NULL; n = col;
} } else if (col > 0 && n != col) {
// End of row fprintf(stderr, "ERROR: File not properly formatted.\n");
if(col != 0) { return NULL;
row++; }
col = 0; // End of row
} if (col != 0) {
} row++;
} col = 0;
// Close file }
fclose(fp); }
return graphs; }
// Close file
fclose(fp);
return graphs;
} }
/*** /***
@ -114,15 +118,15 @@ int* read_graphs(char* filename, int *cnt, int *maxdim) {
* Returns 0 if we run out of interventions, and 1 otherwise. * Returns 0 if we run out of interventions, and 1 otherwise.
***/ ***/
int nextintervention(int n, int *interventionslen, int *interventionidx) { int nextintervention(int n, int *interventionslen, int *interventionidx) {
for(int i=0; i<n; i++) { for (int i=0; i < n; i++) {
if(interventionidx[i] < interventionslen[i] - 1) { if (interventionidx[i] < interventionslen[i] - 1) {
interventionidx[i]++; interventionidx[i]++;
for(int j=0; j<i; j++) for (int j=0; j < i; j++)
interventionidx[j] = 0; interventionidx[j] = 0;
return 1; return 1;
} }
} }
return 0; return 0;
} }
/*** /***
@ -132,18 +136,21 @@ int nextintervention(int n, int *interventionslen, int *interventionidx) {
* If `party' has no parents, then `party' will definitely receive a 1. * If `party' has no parents, then `party' will definitely receive a 1.
* If the fixed-point value cannot be inferred, return -1. * If the fixed-point value cannot be inferred, return -1.
***/ ***/
int alphapre(int party, const int *parents, const int *parentslen, const int *interventions, const int *interventionidx, int maxn) { int alphapre(int party, const int *parents, const int *parentslen, \
if(parentslen[party] == 0) const int *interventions, const int *interventionidx, int maxn) {
return 1; if (parentslen[party] == 0)
const int idatasize = (maxn+1)*(maxn+1)*2; // Max nr of interventions/party return 1;
for(int pidx=0; pidx<parentslen[party]; pidx++) { const int idatasize = (maxn+1)*(maxn+1)*2; // Max nr of interventions/party
const int parent = parents[maxn*party + pidx]; for (int pidx = 0; pidx < parentslen[party]; pidx++) {
const int f0 = interventions[idatasize*parent + 2*interventionidx[parent] + 0]; const int parent = parents[maxn*party + pidx];
const int f1 = interventions[idatasize*parent + 2*interventionidx[parent] + 1]; const int f0 = interventions[idatasize*parent + \
if(f0 != party && f1 != party) 2*interventionidx[parent] + 0];
return 0; const int f1 = interventions[idatasize*parent + \
} 2*interventionidx[parent] + 1];
return -1; if (f0 != party && f1 != party)
return 0;
}
return -1;
} }
/*** /***
@ -154,37 +161,43 @@ int alphapre(int party, const int *parents, const int *parentslen, const int *in
* *
* Make sure to run alphapre before running this. * Make sure to run alphapre before running this.
***/ ***/
int alpha(int *path, int pathlen, const int *parents, const int *parentslen, const int *interventions, const int *interventionidx, const int *fp, int n, int maxn) { int alpha(int *path, int pathlen, const int *parents, const int *parentslen, \
const int party = path[pathlen-1]; const int *interventions, const int *interventionidx, const int *fp, \
for(int i=0;i<pathlen-1;i++) { int n, int maxn) {
if(party == path[i]) { const int party = path[pathlen-1];
return 0; for (int i = 0; i < pathlen-1; i++) {
} if (party == path[i]) {
} return 0;
const int idatasize = (maxn+1)*(maxn+1)*2; // Max nr of interventions/party }
// Iterate over all parents }
// If one parent does not vote for `party', immediattely return a zero. const int idatasize = (maxn+1)*(maxn+1)*2; // Max nr of interventions/party
// If all parents vote for `party' --- which can only be inferred after we queried all parents --- return a one. // Iterate over all parents
for(int pidx=0; pidx<parentslen[party]; pidx++) { // If one parent does not vote for `party', immediattely return a zero.
const int parent = parents[maxn*party + pidx]; // If all parents vote for `party' --- which can only be inferred after we
const int f0 = interventions[idatasize*parent + 2*interventionidx[parent] + 0]; // queried all parents --- return a one.
const int f1 = interventions[idatasize*parent + 2*interventionidx[parent] + 1]; for (int pidx = 0; pidx < parentslen[party]; pidx++) {
if(f0 == party && f1 == party) const int parent = parents[maxn*party + pidx];
continue; const int f0 = interventions[idatasize*parent + 2*interventionidx[parent] \
// Re-use already computed fixed points, else enter recursion + 0];
int val; const int f1 = interventions[idatasize*parent + 2*interventionidx[parent] \
if(fp[parent] != -1) { + 1];
val = fp[parent]; if (f0 == party && f1 == party)
} else { continue;
path[pathlen] = parent; // Re-use already computed fixed points, else enter recursion
val = alpha(path, pathlen+1, parents, parentslen, interventions, interventionidx, fp, n, maxn); int val;
} if (fp[parent] != -1) {
// Evaluate the intervention on the input val = fp[parent];
const int muOfVal = (val == 0) ? f0 : f1; } else {
if(muOfVal != party) path[pathlen] = parent;
return 0; val = alpha(path, pathlen+1, parents, parentslen, interventions, \
} interventionidx, fp, n, maxn);
return 1; }
// Evaluate the intervention on the input
const int muOfVal = (val == 0) ? f0 : f1;
if (muOfVal != party)
return 0;
}
return 1;
} }
/*** /***
@ -192,12 +205,12 @@ int alpha(int *path, int pathlen, const int *parents, const int *parentslen, con
* Helper function for pretty printing. * Helper function for pretty printing.
***/ ***/
int ceillog10(int x) { int ceillog10(int x) {
int res = 0; int res = 0;
while(x > 0) { while (x > 0) {
x /= 10; x /= 10;
res++; res++;
} }
return res; return res;
} }
/*** /***
@ -212,193 +225,214 @@ int ceillog10(int x) {
* Return -1 on error. * Return -1 on error.
***/ ***/
int test_graphs(int startidx, int len, int maxn, const int *graphs) { int test_graphs(int startidx, int len, int maxn, const int *graphs) {
const int gdatasize = maxn * maxn + 1; // Size allocation per graph const int gdatasize = maxn * maxn + 1; // Size allocation per graph
const int idatasize = (maxn+1)*(maxn+1)*2; // Max number of interventions per party const int idatasize = (maxn+1)*(maxn+1)*2; // Max number of interventions
int range[maxn+1]; // Range of intervention // per party
int interventions[maxn*idatasize]; // Hold all interventions per party {f_0(0), f_0(1), g_0(0), g_0(1), ... , f_1(0), f_1(1), ...} int range[maxn+1]; // Range of intervention
int interventionslen[maxn]; // Number of interventions per party int interventions[maxn*idatasize]; // Hold all interventions per
int interventionidx[maxn]; // Current intervention executed // party {f_0(0), f_0(1),
int parents[maxn*maxn]; // List all parents per party // g_0(0), g_0(1), ... ,
int parentslen[maxn]; // Number of parents per party // f_1(0), f_1(1), ...}
int children[maxn*maxn]; // List all children per party int interventionslen[maxn]; // Number of intervention per
int childrenlen[maxn]; // Numer of children per party // party
const int padlen = ceillog10(len); int interventionidx[maxn]; // Current intervention executed
time_t t0 = time(NULL); int parents[maxn*maxn]; // List all parents per party
const time_t tstart = t0; int parentslen[maxn]; // Number of parents per party
for(int graphidx=startidx; graphidx<startidx+len; graphidx++) { int children[maxn*maxn]; // List all children per party
time_t t1 = time(NULL); int childrenlen[maxn]; // Numer of children per party
if(t1 > t0) { const int padlen = ceillog10(len);
const int count = graphidx - startidx + 1; time_t t0 = time(NULL);
const float percentage = 100*(float)count/(float)len; const time_t tstart = t0;
const int deltat = t1-tstart; for (int graphidx = startidx; graphidx < startidx+len; graphidx++) {
const float rate = (float)count/(float)deltat; time_t t1 = time(NULL);
fprintf(stderr, "\r%6.2f%% %*d/%d (%*.2f graphs/s in %d seconds; current line %d)",percentage,padlen,count,len,padlen+3,rate,deltat,graphidx+1); if (t1 > t0) {
t0 = t1; const int count = graphidx - startidx + 1;
} const float percentage = 100*(float)count/(float)len;
// Test graph with index `graphidx' const int deltat = t1-tstart;
// `n' is the order of this graph const float rate = (float)count/(float)deltat;
const int n = graphs[graphidx*gdatasize]; fprintf(stderr, "\r%6.2f%% %*d/%d (%*.2f graphs/s in %d seconds; current line %d)", \
// Get parents and children percentage, padlen, count, len, padlen+3, rate, deltat, graphidx+1);
// Adj matrix is such that (row,col) = 1 <=> edge from row to col t0 = t1;
for(int i=0; i<n; i++) { }
parentslen[i] = 0; // Test graph with index `graphidx'
childrenlen[i] = 0; // `n' is the order of this graph
} const int n = graphs[graphidx*gdatasize];
int idx = 0; // Get parents and children
for(int row=0; row<n; row++) { // Adj matrix is such that (row,col) = 1 <=> edge from row to col
for(int col=0; col<n; col++) { for (int i = 0; i < n; i++) {
if(graphs[graphidx*gdatasize+1+idx] == 1) { parentslen[i] = 0;
// Edge from row to col childrenlen[i] = 0;
children[maxn*row + childrenlen[row]] = col; }
childrenlen[row]++; int idx = 0;
parents[maxn*col + parentslen[col]] = row; for (int row = 0; row < n; row++) {
parentslen[col]++; for (int col = 0; col < n; col++) {
} if (graphs[graphidx*gdatasize+1+idx] == 1) {
idx++; // Edge from row to col
} children[maxn*row + childrenlen[row]] = col;
} childrenlen[row]++;
// Fill in interventions parents[maxn*col + parentslen[col]] = row;
for(int party=0; party<n; party++) { parentslen[col]++;
// This is a small trick to speed-up processing: }
// If the party `party' has two or more children, ignore the `discard' intervention (-1) (tmp=0), idx++;
// else make use of the `discard' internvetion (tmp=1). }
// Populate range of `party's interventions }
// The range has childrenlen[party]+tmp entries // Fill in interventions
range[0] = -1; for (int party = 0; party < n; party++) {
const int tmp = (childrenlen[party]<=1) ? 1 : 0; // This is a small trick to speed-up processing:
for(int j=0; j<childrenlen[party]; j++) { // If the party `party' has two or more children,
range[j+tmp] = children[maxn*party+j]; // ignore the `discard' intervention (-1) (tmp=0),
} // else make use of the `discard' internvetion (tmp=1).
// Enumerate, store, and count all possible interventions // Populate range of `party's interventions
// Each intervention is a tuple (mu(0), mu(1)), x corresponds to the first entry, y to the second // The range has childrenlen[party]+tmp entries
int cnt = 0; range[0] = -1;
for(int x=0; x<childrenlen[party]+tmp; x++) { const int tmp = (childrenlen[party] <= 1) ? 1 : 0;
for(int y=0; y<childrenlen[party]+tmp; y++) { for (int j = 0; j < childrenlen[party]; j++) {
interventions[party*idatasize+2*cnt] = range[x]; range[j+tmp] = children[maxn*party+j];
interventions[party*idatasize+2*cnt+1] = range[y]; }
cnt++; // Enumerate, store, and count all possible interventions
} // Each intervention is a tuple (mu(0), mu(1)), x corresponds to the first
interventionslen[party] = cnt; // entry, y to the second
} int cnt = 0;
} for (int x = 0; x < childrenlen[party]+tmp; x++) {
// Loop over intervetions and verify fixed-point expression for (int y = 0; y < childrenlen[party]+tmp; y++) {
int fp[n]; // Array to store alpha(party) values interventions[party*idatasize+2*cnt] = range[x];
int afterfp[n]; // \omega(\mu(fp)) interventions[party*idatasize+2*cnt+1] = range[y];
int path[n+1]; // Current path cnt++;
for(int i=0; i<n; i++) interventionidx[i] = 0; // Initialize intervention index to the first intervention }
int running = 1; // Flag to see whether we are still verifying, or we verified all interventions interventionslen[party] = cnt;
while(running) { }
// Reset fixed-point entries }
for(int party=0; party<n; party++) // Loop over intervetions and verify fixed-point expression
fp[party] = -1; int fp[n]; // Array to store alpha(party) values
// Fill out fixed-points that are trivially computed int afterfp[n]; // \omega(\mu(fp))
for(int party=0; party<n; party++) int path[n+1]; // Current path
alphapre(party, parents, parentslen, interventions, interventionidx, maxn); // Initialize intervention index to the first intervention
// Invoke recursive function for (int i = 0; i < n; i++) interventionidx[i] = 0;
for(int party=0; party<n; party++) { // Flag to see whether we are still verifying, or we verified all
path[0] = party; // interventions
const int val = alpha(path, 1, parents, parentslen, interventions, interventionidx, fp, n, maxn); int running = 1;
fp[party] = val; while (running) {
} // Reset fixed-point entries
for (int party = 0; party < n; party++)
fp[party] = -1;
// Fill out fixed-points that are trivially computed
for (int party = 0; party < n; party++)
alphapre(party, parents, parentslen, interventions, interventionidx, \
maxn);
// Invoke recursive function
for (int party = 0; party < n; party++) {
path[0] = party;
const int val = alpha(path, 1, parents, parentslen, interventions, \
interventionidx, fp, n, maxn);
fp[party] = val;
}
// Compute \omega(\mu(fp)) // Compute \omega(\mu(fp))
for(int i=0; i<n; i++) for (int i = 0; i < n; i++)
afterfp[i] = -1; afterfp[i] = -1;
// Loop over parties // Loop over parties
for(int party=0; party<n; party++) { for (int party = 0; party < n; party++) {
// Loop over parents of this party // Loop over parents of this party
for(int pidx=0; pidx<parentslen[party]; pidx++) { for (int pidx = 0; pidx < parentslen[party]; pidx++) {
const int parent = parents[maxn*party + pidx]; const int parent = parents[maxn*party + pidx];
const int f0 = interventions[idatasize*parent + 2*interventionidx[parent] + 0]; const int f0 = interventions[idatasize*parent + \
const int f1 = interventions[idatasize*parent + 2*interventionidx[parent] + 1]; 2*interventionidx[parent] + 0];
// If `parent' never votes for `party', this value is 0. const int f1 = interventions[idatasize*parent + \
if(f0 != party && f1 != party) { 2*interventionidx[parent] + 1];
afterfp[party] = 0; // If `parent' never votes for `party', this value is 0.
break; if (f0 != party && f1 != party) {
} afterfp[party] = 0;
// If `parent' always votes for `party', check the other parents. break;
if(f0 == party && f1 == party) }
continue; // If `parent' always votes for `party', check the other parents.
// Evaluate intervention on the input (fp[parent]) if (f0 == party && f1 == party)
const int muOfVal = (fp[parent] == 0) ? f0 : f1; continue;
// If `parent' does not vote for `party', this value is 0, else check the other parents. // Evaluate intervention on the input (fp[parent])
if(muOfVal != party) { const int muOfVal = (fp[parent] == 0) ? f0 : f1;
afterfp[party] = 0; // If `parent' does not vote for `party', this value is 0, else check
break; // the other parents.
} if (muOfVal != party) {
afterfp[party] = 0;
break;
}
}
// All parents voted `party'
if (afterfp[party] == -1)
afterfp[party] = 1;
}
// Compare the output of the recursive alpha function (fp) with
// \omega(\mu(fp)) (afterfp)
// If these two arrays differ, return the line number of the graph we
// falsified
for (int party = 0; party < n; party++)
if (fp[party] != afterfp[party])
return graphidx+1;
} // Next intervention
// All parents voted `party' running = nextintervention(n, interventionslen, interventionidx);
if(afterfp[party] == -1) }
afterfp[party] = 1; }
} const int deltat = time(NULL) - tstart;
// Compare the output of the recursive alpha function (fp) with \omega(\mu(fp)) (afterfp) const float rate = (deltat == 0) ? len : (float)len/(float)deltat;
// If these two arrays differ, return the line number of the graph we falsified fprintf(stderr, "\r%6.2f%% %*d/%d (%*.2f graphs/s in %d seconds; current line %d)\n", \
for(int party=0;party<n;party++) 100.0, padlen, len, len, padlen+3, rate, deltat, startidx+len);
if(fp[party] != afterfp[party]) return 0;
return graphidx+1;
// Next intervention
running = nextintervention(n, interventionslen, interventionidx);
}
}
const int deltat = time(NULL) - tstart;
const float rate = (deltat == 0) ? len : (float)len/(float)deltat;
fprintf(stderr, "\r%6.2f%% %*d/%d (%*.2f graphs/s in %d seconds; current line %d)\n",100.0,padlen,len,len,padlen+3,rate,deltat,startidx+len);
return 0;
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
// Parse command-line arguments // Parse command-line arguments
int START = 0; int START = 0;
int NUM = 0; int NUM = 0;
if(argc >= 3) if (argc >= 3)
START = atoi(argv[2]); START = atoi(argv[2]);
if(argc >= 4) { if (argc >= 4) {
if(argv[3][0] == '+') if (argv[3][0] == '+')
NUM = atoi(argv[3]+1); NUM = atoi(argv[3]+1);
else else
NUM = atoi(argv[3])-START+1; NUM = atoi(argv[3])-START+1;
} }
if(!(argc >= 2 && (argc < 3 || START > 0) && (argc < 4 || NUM > 0) && argc <= 4)) { if (!(argc >= 2 && (argc < 3 || START > 0) && (argc < 4 || NUM > 0) && \
fprintf(stderr, "Usage: %s <filename> [<startline> [<endline> | +<count>]]\n", argv[0]); argc <= 4)) {
fprintf(stderr, " <filename> File name with adjacency matrices of simple directed graphs\n"); fprintf(stderr, "Usage: %s <filename> [<startline> [<endline> | +<count>]]\n", argv[0]);
fprintf(stderr, " <startline> Verify graphs starting from line `startline'\n"); fprintf(stderr, " <filename> File name with adjacency matrices of simple directed graphs\n");
fprintf(stderr, " <endline> Verify graphs up to and including line `endline'\n"); fprintf(stderr, " <startline> Verify graphs starting from line `startline'\n");
fprintf(stderr, " +<count> Verify `count' number of graphs\n"); fprintf(stderr, " <endline> Verify graphs up to and including line `endline'\n");
fprintf(stderr, "\n"); fprintf(stderr, " +<count> Verify `count' number of graphs\n");
fprintf(stderr, "[FILE FORMAT]\n"); fprintf(stderr, "\n");
fprintf(stderr, " Each line in `filename' must contain the adjacency matrix of a simple directed graph in the format\n"); fprintf(stderr, "[FILE FORMAT]\n");
fprintf(stderr, " {{a00,a01,...},{a10,a11,...},...} where aij=1 if and only if the graph has the edge i -> j\n"); fprintf(stderr, " Each line in `filename' must contain the adjacency matrix of a simple directed graph in the format\n");
fprintf(stderr, " The file `filename' may contain graphs with different order (number of vertices)\n"); fprintf(stderr, " {{a00,a01,...},{a10,a11,...},...} where aij=1 if and only if the graph has the edge i -> j\n");
fprintf(stderr, "\n"); fprintf(stderr, " The file `filename' may contain graphs with different order (number of vertices)\n");
fprintf(stderr, "This program verifies the admissibility of simple directed graphs.\n"); fprintf(stderr, "\n");
return -1; fprintf(stderr, "This program verifies the admissibility of simple directed graphs.\n");
} return -1;
}
// Read Graphs from File // Read Graphs from File
int graphcount = 0; int graphcount = 0;
int maxdimension = -1; int maxdimension = -1;
const int *graphs = read_graphs(argv[1], &graphcount, &maxdimension); const int *graphs = read_graphs(argv[1], &graphcount, &maxdimension);
if(graphs == NULL) { if (graphs == NULL) {
fprintf(stderr, "ERROR: Could not read graphs from file `%s'.\n", argv[1]); fprintf(stderr, "ERROR: Could not read graphs from file `%s'.\n", argv[1]);
return -1; return -1;
} }
const int startidx = START ? START-1 : 0; // Index of graph to start verifying const int startidx = START ? START-1 : 0; // Index of graph to start verifying
const int tot = NUM ? NUM : graphcount-startidx; // Number of graphs to be verified const int tot = NUM ? NUM : graphcount-startidx; // Number of graphs to be verified
if(startidx >= graphcount || tot <= 0 || tot+startidx-1 >= graphcount) { if (startidx >= graphcount || tot <= 0 || tot+startidx-1 >= graphcount) {
fprintf(stderr, "ERROR: Lines to be verified are out of range\n"); fprintf(stderr, "ERROR: Lines to be verified are out of range\n");
return -1; return -1;
} }
// Test `tot' graphs, starting from index `startidx' // Test `tot' graphs, starting from index `startidx'
printf("Verifying the admissibility of %d graphs in the file `%s' (line %d to line %d)\n", tot, argv[1], startidx+1, startidx+tot); printf("Verifying the admissibility of %d graphs in the file `%s' (line %d to line %d)\n", \
const int result = test_graphs(startidx, tot, maxdimension, graphs); tot, argv[1], startidx+1, startidx+tot);
if (result == 0) const int result = test_graphs(startidx, tot, maxdimension, graphs);
printf("These graphs are admissible\n"); if (result == 0)
else if(result == -1) printf("These graphs are admissible\n");
fprintf(stderr, "ERROR: Something went wrong\n"); else if (result == -1)
else fprintf(stderr, "ERROR: Something went wrong\n");
printf("The function alpha does not represent the fixed point, or the graph on line %d is inadmissible\n", result); else
return result; printf("The function alpha does not represent the fixed point, or the graph on line %d is inadmissible\n", \
result);
return result;
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,80 +1,80 @@
// SPDX-FileCopyrightText: 2023 Ämin Baumeler <amin@indyfac.ch> and Eleftherios-Ermis Tselentis <eleftheriosermis.tselentis@oeaw.ac.at> // SPDX-FileCopyrightText: 2023 Ämin Baumeler <amin@indyfac.ch> and
// Eleftherios-Ermis Tselentis <eleftheriosermis.tselentis@oeaw.ac.at>
// //
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#include <stdio.h> #include <stdio.h>
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
// Parse command-line arguments // Parse command-line arguments
if(argc != 2) { if (argc != 2) {
fprintf(stderr, "Usage: %s <filename>\n", argv[0]); fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
fprintf(stderr, " <filename> File name with adjacency matrices of simple directed graphs\n"); fprintf(stderr, " <filename> File name with adjacency matrices of simple directed graphs\n");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, "[FILE FORMAT]\n"); fprintf(stderr, "[FILE FORMAT]\n");
fprintf(stderr, " Each line in `filename' must contain the adjacency matrix of a simple directed graph in the format\n"); fprintf(stderr, " Each line in `filename' must contain the adjacency matrix of a simple directed graph in the format\n");
fprintf(stderr, " {{a00,a01,...},{a10,a11,...},...} where aij=1 if and only if the graph has the edge i -> j\n"); fprintf(stderr, " {{a00,a01,...},{a10,a11,...},...} where aij=1 if and only if the graph has the edge i -> j\n");
fprintf(stderr, " The file `filename' may contain graphs with different order (number of vertices)\n"); fprintf(stderr, " The file `filename' may contain graphs with different order (number of vertices)\n");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, "This program translates to adjacency matrices into the Graphviz format, and prints them to stdout.\n"); fprintf(stderr, "This program translates to adjacency matrices into the Graphviz format, and prints them to stdout.\n");
return -1; return -1;
} }
// Open file // Open file
FILE *fp; FILE *fp;
fp = fopen(argv[1], "r"); fp = fopen(argv[1], "r");
if(fp == NULL){ if (fp == NULL) {
fprintf(stderr, "ERROR: Could not read graphs from file `%s'.\n", argv[1]); fprintf(stderr, "ERROR: Could not read graphs from file `%s'.\n", argv[1]);
return -1; return -1;
} }
// Parse // Parse
int headprinted = 1; int headprinted = 1;
int line = 1; int line = 1;
int n = -1; int n = -1;
int row = 0; int row = 0;
int col = 0; int col = 0;
char ch; printf("strict digraph \"File_%s_line_%d\" {", argv[1], line);
printf("strict digraph \"File_%s_line_%d\" {", argv[1], line); while (!feof(fp)) {
while(!feof(fp)) { char ch = fgetc(fp);
ch = fgetc(fp); switch (ch) {
switch(ch) { case '{':
case '{': if (row == 0 && col == 0 && headprinted == 0) {
if(row==0 && col==0 && headprinted==0) { headprinted = 1;
headprinted = 1; printf("strict digraph \"File_%s_line_%d\" {", argv[1], line);
printf("strict digraph \"File_%s_line_%d\" {", argv[1], line); }
} break;
break; case '0':
case '0': case '1':
case '1': if (ch == '1')
if(ch=='1') printf("G%dN%d->G%dN%d;", line, row, line, col);
printf("G%dN%d->G%dN%d;", line,row,line,col); col++;
col++; break;
break; case '}':
case '}': if (n == -1)
if(n==-1) n = col;
n = col; if (col == n) {
if(col==n) { row++;
row++; col = 0;
col=0; }
} break;
break; case '\n':
case '\n': printf("}\n");
printf("}\n"); headprinted = 0;
headprinted = 0; line++;
line++; row = 0;
row = 0; col = 0;
col = 0; n = -1;
n = -1; break;
break; case ',':
case ',': case ' ':
case ' ': case 0xffffffff:
case 0xffffffff: break;
break; default:
default: fprintf(stderr, "File contains wrongly formatted graph\n");
fprintf(stderr, "File contains wrongly formatted graph\n"); fclose(fp);
fclose(fp); return -1; // Format error
return -1; // Format error }
} }
} fclose(fp);
fclose(fp); return 0;
return 0;
} }

View File

@ -1,6 +1,7 @@
#!/usr/bin/python3 #!/usr/bin/python3
""" """
SPDX-FileCopyrightText: 2023 Ämin Baumeler <amin@indyfac.ch> and Eleftherios-Ermis Tselentis <eleftheriosermis.tselentis@oeaw.ac.at> SPDX-FileCopyrightText: 2023 Ämin Baumeler <amin@indyfac.ch> and
Eleftherios-Ermis Tselentis <eleftheriosermis.tselentis@oeaw.ac.at>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-or-later
""" """