replaced tabs with whitespace, linted c code, reduced line lengths if possible for better readability
This commit is contained in:
parent
ab5a90dc38
commit
642b78c900
@ -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;
|
||||||
}
|
}
|
||||||
|
918
src/SOCgen.c
918
src/SOCgen.c
File diff suppressed because it is too large
Load Diff
@ -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;
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user