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
@ -8,10 +9,10 @@
/***
* Read graphs from file.
* Input `filename': string
* Input `cnt': pointer to int
* Input `maxdim': pointer to int
* Output: pointer to graph data
* Input `filename': string
* Input `cnt': pointer to int
* Input `maxdim': pointer to int
* Output: pointer to graph data
*
* 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,
@ -20,93 +21,96 @@
* The ith graph is at position i*(maxdim*maxdim + 1).
***/
int* read_graphs(char* filename, int *cnt, int *maxdim) {
// Open file
FILE *fp;
fp = fopen(filename, "r");
if(fp == NULL)
return NULL;
// Count number of lines, allocate space and initiate counter
char ch;
int n = 0;
*cnt = 0; // Total number of graphs
*maxdim = 0; // Maximum number of vertices
while(!feof(fp)) {
ch = fgetc(fp);
switch(ch) {
case '\n':
(*cnt)++;
n = 0;
break;
case '{':
case '}':
*maxdim = (n > *maxdim) ? n : *maxdim;
n = 0;
break;
case '0':
case '1':
n++;
break;
case ',':
case ' ':
case 0xffffffff:
break;
default:
return NULL; // Format error
}
}
rewind(fp); // Return to start of file
// Open file
FILE *fp;
fp = fopen(filename, "r");
if (fp == NULL)
return NULL;
// Count number of lines, allocate space and initiate counter
char ch;
int n = 0;
*cnt = 0; // Total number of graphs
*maxdim = 0; // Maximum number of vertices
while (!feof(fp)) {
ch = fgetc(fp);
switch (ch) {
case '\n':
(*cnt)++;
n = 0;
break;
case '{':
case '}':
*maxdim = (n > *maxdim) ? n : *maxdim;
n = 0;
break;
case '0':
case '1':
n++;
break;
case ',':
case ' ':
case 0xffffffff:
break;
default:
return NULL; // Format error
}
}
rewind(fp); // Return to start of file
// Allocate space for graph data
const int gdatasize = *maxdim * *maxdim + 1; // Size allocation per graph
const int arraysize = (1+ *cnt) * gdatasize; // Total space to allocate
int *graphs = (int*)malloc(sizeof(int)*arraysize); // Allocation
if(!graphs) {
fprintf(stderr, "ERROR: Could not allocate enough memory to store the graphs.\n");
return NULL;
}
// Parse file
int col = 0; // Column number
int row = 0; // Row number
int i = 0; // Current graph index
n = -1; // Graph dimension
int j = 0; // Running index
while ((ch = fgetc(fp)) != EOF) {
// New line encountered
if(ch == '\n') {
if(row != n) {
fprintf(stderr, "ERROR: File not properly formatted.\n");
return NULL;
}
graphs[i*gdatasize] = n;
i++;
j = 0;
col = 0;
row = 0;
n = -1;
// Matrix entry encountered
} else if(ch == '0' || ch == '1') {
int x = ch - '0';
graphs[i*gdatasize + 1 + j] = x;
col++;
j++;
// End-of-row or end-of-matrix encountered
} else if(ch == '}') {
if(n == -1) {
n = col;
} else if(col > 0 && n != col) {
fprintf(stderr, "ERROR: File not properly formatted.\n");
return NULL;
}
// End of row
if(col != 0) {
row++;
col = 0;
}
}
}
// Close file
fclose(fp);
return graphs;
// Allocate space for graph data
// Size allocation per graph
const int gdatasize = *maxdim * *maxdim + 1;
// Total space to allocate
const int arraysize = (1+ *cnt) * gdatasize;
// Allocation
int *graphs = (int*)malloc(sizeof(int)*arraysize);
if (!graphs) {
fprintf(stderr, "ERROR: Could not allocate enough memory to store the graphs.\n");
return NULL;
}
// Parse file
int col = 0; // Column number
int row = 0; // Row number
int i = 0; // Current graph index
n = -1; // Graph dimension
int j = 0; // Running index
while ((ch = fgetc(fp)) != EOF) {
// New line encountered
if (ch == '\n') {
if (row != n) {
fprintf(stderr, "ERROR: File not properly formatted.\n");
return NULL;
}
graphs[i*gdatasize] = n;
i++;
j = 0;
col = 0;
row = 0;
n = -1;
// Matrix entry encountered
} else if (ch == '0' || ch == '1') {
int x = ch - '0';
graphs[i*gdatasize + 1 + j] = x;
col++;
j++;
// End-of-row or end-of-matrix encountered
} else if (ch == '}') {
if (n == -1) {
n = col;
} else if (col > 0 && n != col) {
fprintf(stderr, "ERROR: File not properly formatted.\n");
return NULL;
}
// End of row
if (col != 0) {
row++;
col = 0;
}
}
}
// 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.
***/
int nextintervention(int n, int *interventionslen, int *interventionidx) {
for(int i=0; i<n; i++) {
if(interventionidx[i] < interventionslen[i] - 1) {
interventionidx[i]++;
for(int j=0; j<i; j++)
interventionidx[j] = 0;
return 1;
}
}
return 0;
for (int i=0; i < n; i++) {
if (interventionidx[i] < interventionslen[i] - 1) {
interventionidx[i]++;
for (int j=0; j < i; j++)
interventionidx[j] = 0;
return 1;
}
}
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 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) {
if(parentslen[party] == 0)
return 1;
const int idatasize = (maxn+1)*(maxn+1)*2; // Max nr of interventions/party
for(int pidx=0; pidx<parentslen[party]; pidx++) {
const int parent = parents[maxn*party + pidx];
const int f0 = interventions[idatasize*parent + 2*interventionidx[parent] + 0];
const int f1 = interventions[idatasize*parent + 2*interventionidx[parent] + 1];
if(f0 != party && f1 != party)
return 0;
}
return -1;
int alphapre(int party, const int *parents, const int *parentslen, \
const int *interventions, const int *interventionidx, int maxn) {
if (parentslen[party] == 0)
return 1;
const int idatasize = (maxn+1)*(maxn+1)*2; // Max nr of interventions/party
for (int pidx = 0; pidx < parentslen[party]; pidx++) {
const int parent = parents[maxn*party + pidx];
const int f0 = interventions[idatasize*parent + \
2*interventionidx[parent] + 0];
const int f1 = interventions[idatasize*parent + \
2*interventionidx[parent] + 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.
***/
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) {
const int party = path[pathlen-1];
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.
// If all parents vote for `party' --- which can only be inferred after we queried all parents --- return a one.
for(int pidx=0; pidx<parentslen[party]; pidx++) {
const int parent = parents[maxn*party + pidx];
const int f0 = interventions[idatasize*parent + 2*interventionidx[parent] + 0];
const int f1 = interventions[idatasize*parent + 2*interventionidx[parent] + 1];
if(f0 == party && f1 == party)
continue;
// Re-use already computed fixed points, else enter recursion
int val;
if(fp[parent] != -1) {
val = fp[parent];
} else {
path[pathlen] = parent;
val = alpha(path, pathlen+1, parents, parentslen, interventions, interventionidx, fp, n, maxn);
}
// Evaluate the intervention on the input
const int muOfVal = (val == 0) ? f0 : f1;
if(muOfVal != party)
return 0;
}
return 1;
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) {
const int party = path[pathlen-1];
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.
// If all parents vote for `party' --- which can only be inferred after we
// queried all parents --- return a one.
for (int pidx = 0; pidx < parentslen[party]; pidx++) {
const int parent = parents[maxn*party + pidx];
const int f0 = interventions[idatasize*parent + 2*interventionidx[parent] \
+ 0];
const int f1 = interventions[idatasize*parent + 2*interventionidx[parent] \
+ 1];
if (f0 == party && f1 == party)
continue;
// Re-use already computed fixed points, else enter recursion
int val;
if (fp[parent] != -1) {
val = fp[parent];
} else {
path[pathlen] = parent;
val = alpha(path, pathlen+1, parents, parentslen, interventions, \
interventionidx, fp, n, maxn);
}
// 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.
***/
int ceillog10(int x) {
int res = 0;
while(x > 0) {
x /= 10;
res++;
}
return res;
int res = 0;
while (x > 0) {
x /= 10;
res++;
}
return res;
}
/***
@ -212,193 +225,214 @@ int ceillog10(int x) {
* Return -1 on error.
***/
int test_graphs(int startidx, int len, int maxn, const int *graphs) {
const int gdatasize = maxn * maxn + 1; // Size allocation per graph
const int idatasize = (maxn+1)*(maxn+1)*2; // Max number of interventions per party
int range[maxn+1]; // Range of intervention
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 interventionslen[maxn]; // Number of interventions per party
int interventionidx[maxn]; // Current intervention executed
int parents[maxn*maxn]; // List all parents per party
int parentslen[maxn]; // Number of parents per party
int children[maxn*maxn]; // List all children per party
int childrenlen[maxn]; // Numer of children per party
const int padlen = ceillog10(len);
time_t t0 = time(NULL);
const time_t tstart = t0;
for(int graphidx=startidx; graphidx<startidx+len; graphidx++) {
time_t t1 = time(NULL);
if(t1 > t0) {
const int count = graphidx - startidx + 1;
const float percentage = 100*(float)count/(float)len;
const int deltat = t1-tstart;
const float rate = (float)count/(float)deltat;
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);
t0 = t1;
}
// Test graph with index `graphidx'
// `n' is the order of this graph
const int n = graphs[graphidx*gdatasize];
// Get parents and children
// Adj matrix is such that (row,col) = 1 <=> edge from row to col
for(int i=0; i<n; i++) {
parentslen[i] = 0;
childrenlen[i] = 0;
}
int idx = 0;
for(int row=0; row<n; row++) {
for(int col=0; col<n; col++) {
if(graphs[graphidx*gdatasize+1+idx] == 1) {
// Edge from row to col
children[maxn*row + childrenlen[row]] = col;
childrenlen[row]++;
parents[maxn*col + parentslen[col]] = row;
parentslen[col]++;
}
idx++;
}
}
// Fill in interventions
for(int party=0; party<n; party++) {
// 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),
// else make use of the `discard' internvetion (tmp=1).
// Populate range of `party's interventions
// The range has childrenlen[party]+tmp entries
range[0] = -1;
const int tmp = (childrenlen[party]<=1) ? 1 : 0;
for(int j=0; j<childrenlen[party]; j++) {
range[j+tmp] = children[maxn*party+j];
}
// Enumerate, store, and count all possible interventions
// Each intervention is a tuple (mu(0), mu(1)), x corresponds to the first entry, y to the second
int cnt = 0;
for(int x=0; x<childrenlen[party]+tmp; x++) {
for(int y=0; y<childrenlen[party]+tmp; y++) {
interventions[party*idatasize+2*cnt] = range[x];
interventions[party*idatasize+2*cnt+1] = range[y];
cnt++;
}
interventionslen[party] = cnt;
}
}
// Loop over intervetions and verify fixed-point expression
int fp[n]; // Array to store alpha(party) values
int afterfp[n]; // \omega(\mu(fp))
int path[n+1]; // Current path
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
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;
}
const int gdatasize = maxn * maxn + 1; // Size allocation per graph
const int idatasize = (maxn+1)*(maxn+1)*2; // Max number of interventions
// per party
int range[maxn+1]; // Range of intervention
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 interventionslen[maxn]; // Number of intervention per
// party
int interventionidx[maxn]; // Current intervention executed
int parents[maxn*maxn]; // List all parents per party
int parentslen[maxn]; // Number of parents per party
int children[maxn*maxn]; // List all children per party
int childrenlen[maxn]; // Numer of children per party
const int padlen = ceillog10(len);
time_t t0 = time(NULL);
const time_t tstart = t0;
for (int graphidx = startidx; graphidx < startidx+len; graphidx++) {
time_t t1 = time(NULL);
if (t1 > t0) {
const int count = graphidx - startidx + 1;
const float percentage = 100*(float)count/(float)len;
const int deltat = t1-tstart;
const float rate = (float)count/(float)deltat;
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);
t0 = t1;
}
// Test graph with index `graphidx'
// `n' is the order of this graph
const int n = graphs[graphidx*gdatasize];
// Get parents and children
// Adj matrix is such that (row,col) = 1 <=> edge from row to col
for (int i = 0; i < n; i++) {
parentslen[i] = 0;
childrenlen[i] = 0;
}
int idx = 0;
for (int row = 0; row < n; row++) {
for (int col = 0; col < n; col++) {
if (graphs[graphidx*gdatasize+1+idx] == 1) {
// Edge from row to col
children[maxn*row + childrenlen[row]] = col;
childrenlen[row]++;
parents[maxn*col + parentslen[col]] = row;
parentslen[col]++;
}
idx++;
}
}
// Fill in interventions
for (int party = 0; party < n; party++) {
// 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),
// else make use of the `discard' internvetion (tmp=1).
// Populate range of `party's interventions
// The range has childrenlen[party]+tmp entries
range[0] = -1;
const int tmp = (childrenlen[party] <= 1) ? 1 : 0;
for (int j = 0; j < childrenlen[party]; j++) {
range[j+tmp] = children[maxn*party+j];
}
// Enumerate, store, and count all possible interventions
// Each intervention is a tuple (mu(0), mu(1)), x corresponds to the first
// entry, y to the second
int cnt = 0;
for (int x = 0; x < childrenlen[party]+tmp; x++) {
for (int y = 0; y < childrenlen[party]+tmp; y++) {
interventions[party*idatasize+2*cnt] = range[x];
interventions[party*idatasize+2*cnt+1] = range[y];
cnt++;
}
interventionslen[party] = cnt;
}
}
// Loop over intervetions and verify fixed-point expression
int fp[n]; // Array to store alpha(party) values
int afterfp[n]; // \omega(\mu(fp))
int path[n+1]; // Current path
// Initialize intervention index to the first intervention
for (int i = 0; i < n; i++) interventionidx[i] = 0;
// Flag to see whether we are still verifying, or we verified all
// interventions
int running = 1;
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))
for(int i=0; i<n; i++)
afterfp[i] = -1;
// Loop over parties
for(int party=0; party<n; party++) {
// Loop over parents of this party
for(int pidx=0; pidx<parentslen[party]; pidx++) {
const int parent = parents[maxn*party + pidx];
const int f0 = interventions[idatasize*parent + 2*interventionidx[parent] + 0];
const int f1 = interventions[idatasize*parent + 2*interventionidx[parent] + 1];
// If `parent' never votes for `party', this value is 0.
if(f0 != party && f1 != party) {
afterfp[party] = 0;
break;
}
// If `parent' always votes for `party', check the other parents.
if(f0 == party && f1 == party)
continue;
// Evaluate intervention on the input (fp[parent])
const int muOfVal = (fp[parent] == 0) ? f0 : f1;
// If `parent' does not vote for `party', this value is 0, else check the other parents.
if(muOfVal != party) {
afterfp[party] = 0;
break;
}
// Compute \omega(\mu(fp))
for (int i = 0; i < n; i++)
afterfp[i] = -1;
// Loop over parties
for (int party = 0; party < n; party++) {
// Loop over parents of this party
for (int pidx = 0; pidx < parentslen[party]; pidx++) {
const int parent = parents[maxn*party + pidx];
const int f0 = interventions[idatasize*parent + \
2*interventionidx[parent] + 0];
const int f1 = interventions[idatasize*parent + \
2*interventionidx[parent] + 1];
// If `parent' never votes for `party', this value is 0.
if (f0 != party && f1 != party) {
afterfp[party] = 0;
break;
}
// If `parent' always votes for `party', check the other parents.
if (f0 == party && f1 == party)
continue;
// Evaluate intervention on the input (fp[parent])
const int muOfVal = (fp[parent] == 0) ? f0 : f1;
// If `parent' does not vote for `party', this value is 0, else check
// 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;
}
// 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
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;
// 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[]) {
// Parse command-line arguments
int START = 0;
int NUM = 0;
if(argc >= 3)
START = atoi(argv[2]);
if(argc >= 4) {
if(argv[3][0] == '+')
NUM = atoi(argv[3]+1);
else
NUM = atoi(argv[3])-START+1;
}
if(!(argc >= 2 && (argc < 3 || START > 0) && (argc < 4 || NUM > 0) && argc <= 4)) {
fprintf(stderr, "Usage: %s <filename> [<startline> [<endline> | +<count>]]\n", argv[0]);
fprintf(stderr, " <filename> File name with adjacency matrices of simple directed graphs\n");
fprintf(stderr, " <startline> Verify graphs starting from line `startline'\n");
fprintf(stderr, " <endline> Verify graphs up to and including line `endline'\n");
fprintf(stderr, " +<count> Verify `count' number of graphs\n");
fprintf(stderr, "\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, " {{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, "\n");
fprintf(stderr, "This program verifies the admissibility of simple directed graphs.\n");
return -1;
}
// Parse command-line arguments
int START = 0;
int NUM = 0;
if (argc >= 3)
START = atoi(argv[2]);
if (argc >= 4) {
if (argv[3][0] == '+')
NUM = atoi(argv[3]+1);
else
NUM = atoi(argv[3])-START+1;
}
if (!(argc >= 2 && (argc < 3 || START > 0) && (argc < 4 || NUM > 0) && \
argc <= 4)) {
fprintf(stderr, "Usage: %s <filename> [<startline> [<endline> | +<count>]]\n", argv[0]);
fprintf(stderr, " <filename> File name with adjacency matrices of simple directed graphs\n");
fprintf(stderr, " <startline> Verify graphs starting from line `startline'\n");
fprintf(stderr, " <endline> Verify graphs up to and including line `endline'\n");
fprintf(stderr, " +<count> Verify `count' number of graphs\n");
fprintf(stderr, "\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, " {{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, "\n");
fprintf(stderr, "This program verifies the admissibility of simple directed graphs.\n");
return -1;
}
// Read Graphs from File
int graphcount = 0;
int maxdimension = -1;
const int *graphs = read_graphs(argv[1], &graphcount, &maxdimension);
if(graphs == NULL) {
fprintf(stderr, "ERROR: Could not read graphs from file `%s'.\n", argv[1]);
return -1;
}
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
if(startidx >= graphcount || tot <= 0 || tot+startidx-1 >= graphcount) {
fprintf(stderr, "ERROR: Lines to be verified are out of range\n");
return -1;
}
// Read Graphs from File
int graphcount = 0;
int maxdimension = -1;
const int *graphs = read_graphs(argv[1], &graphcount, &maxdimension);
if (graphs == NULL) {
fprintf(stderr, "ERROR: Could not read graphs from file `%s'.\n", argv[1]);
return -1;
}
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
if (startidx >= graphcount || tot <= 0 || tot+startidx-1 >= graphcount) {
fprintf(stderr, "ERROR: Lines to be verified are out of range\n");
return -1;
}
// 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);
const int result = test_graphs(startidx, tot, maxdimension, graphs);
if (result == 0)
printf("These graphs are admissible\n");
else if(result == -1)
fprintf(stderr, "ERROR: Something went wrong\n");
else
printf("The function alpha does not represent the fixed point, or the graph on line %d is inadmissible\n", result);
return result;
// 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);
const int result = test_graphs(startidx, tot, maxdimension, graphs);
if (result == 0)
printf("These graphs are admissible\n");
else if (result == -1)
fprintf(stderr, "ERROR: Something went wrong\n");
else
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
#include <stdio.h>
int main(int argc, char *argv[]) {
// Parse command-line arguments
if(argc != 2) {
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
fprintf(stderr, " <filename> File name with adjacency matrices of simple directed graphs\n");
fprintf(stderr, "\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, " {{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, "\n");
fprintf(stderr, "This program translates to adjacency matrices into the Graphviz format, and prints them to stdout.\n");
return -1;
}
// Parse command-line arguments
if (argc != 2) {
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
fprintf(stderr, " <filename> File name with adjacency matrices of simple directed graphs\n");
fprintf(stderr, "\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, " {{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, "\n");
fprintf(stderr, "This program translates to adjacency matrices into the Graphviz format, and prints them to stdout.\n");
return -1;
}
// Open file
FILE *fp;
fp = fopen(argv[1], "r");
if(fp == NULL){
fprintf(stderr, "ERROR: Could not read graphs from file `%s'.\n", argv[1]);
return -1;
}
// Parse
int headprinted = 1;
int line = 1;
int n = -1;
int row = 0;
int col = 0;
char ch;
printf("strict digraph \"File_%s_line_%d\" {", argv[1], line);
while(!feof(fp)) {
ch = fgetc(fp);
switch(ch) {
case '{':
if(row==0 && col==0 && headprinted==0) {
headprinted = 1;
printf("strict digraph \"File_%s_line_%d\" {", argv[1], line);
}
break;
case '0':
case '1':
if(ch=='1')
printf("G%dN%d->G%dN%d;", line,row,line,col);
col++;
break;
case '}':
if(n==-1)
n = col;
if(col==n) {
row++;
col=0;
}
break;
case '\n':
printf("}\n");
headprinted = 0;
line++;
row = 0;
col = 0;
n = -1;
break;
case ',':
case ' ':
case 0xffffffff:
break;
default:
fprintf(stderr, "File contains wrongly formatted graph\n");
fclose(fp);
return -1; // Format error
}
}
fclose(fp);
return 0;
// Open file
FILE *fp;
fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "ERROR: Could not read graphs from file `%s'.\n", argv[1]);
return -1;
}
// Parse
int headprinted = 1;
int line = 1;
int n = -1;
int row = 0;
int col = 0;
printf("strict digraph \"File_%s_line_%d\" {", argv[1], line);
while (!feof(fp)) {
char ch = fgetc(fp);
switch (ch) {
case '{':
if (row == 0 && col == 0 && headprinted == 0) {
headprinted = 1;
printf("strict digraph \"File_%s_line_%d\" {", argv[1], line);
}
break;
case '0':
case '1':
if (ch == '1')
printf("G%dN%d->G%dN%d;", line, row, line, col);
col++;
break;
case '}':
if (n == -1)
n = col;
if (col == n) {
row++;
col = 0;
}
break;
case '\n':
printf("}\n");
headprinted = 0;
line++;
row = 0;
col = 0;
n = -1;
break;
case ',':
case ' ':
case 0xffffffff:
break;
default:
fprintf(stderr, "File contains wrongly formatted graph\n");
fclose(fp);
return -1; // Format error
}
}
fclose(fp);
return 0;
}

View File

@ -1,6 +1,7 @@
#!/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
"""