- [[[ Broken commit ]]]
Committing partial new Warshall work because it is getting too big.
This commit is contained in:
parent
8995bc4d28
commit
0ce88af6ac
@ -39,6 +39,7 @@
|
|||||||
#include "prune_theorems.h"
|
#include "prune_theorems.h"
|
||||||
#include "arachne.h"
|
#include "arachne.h"
|
||||||
#include "hidelevel.h"
|
#include "hidelevel.h"
|
||||||
|
#include "depend.h"
|
||||||
|
|
||||||
extern int *graph;
|
extern int *graph;
|
||||||
extern int nodes;
|
extern int nodes;
|
||||||
@ -700,9 +701,9 @@ create_decryptor (const Term term, const Term key)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
globalError++;
|
globalError++;
|
||||||
printf ("Term for which a decryptor instance is requested: ");
|
eprintf ("Term for which a decryptor instance is requested: ");
|
||||||
termPrint (term);
|
termPrint (term);
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
error
|
error
|
||||||
("Trying to build a decryptor instance for a non-encrypted term.");
|
("Trying to build a decryptor instance for a non-encrypted term.");
|
||||||
}
|
}
|
||||||
@ -777,15 +778,15 @@ bind_existing_to_goal (const Binding b, const int run, const int index)
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (DEBUGL (4))
|
if (DEBUGL (4))
|
||||||
{
|
{
|
||||||
printf ("Trying to bind the small term ");
|
eprintf ("Trying to bind the small term ");
|
||||||
termPrint (b->term);
|
termPrint (b->term);
|
||||||
printf (" as coming from the big send ");
|
eprintf (" as coming from the big send ");
|
||||||
termPrint (rd->message);
|
termPrint (rd->message);
|
||||||
printf (" , binding ");
|
eprintf (" , binding ");
|
||||||
termPrint (b->term);
|
termPrint (b->term);
|
||||||
printf ("\nCrypted list needed: ");
|
eprintf ("\nCrypted list needed: ");
|
||||||
termlistPrint (cryptlist);
|
termlistPrint (cryptlist);
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (cryptlist != NULL && switches.output == PROOF)
|
if (cryptlist != NULL && switches.output == PROOF)
|
||||||
@ -893,6 +894,8 @@ bind_existing_to_goal (const Binding b, const int run, const int index)
|
|||||||
indentDepth++;
|
indentDepth++;
|
||||||
flag = flag && iterate ();
|
flag = flag && iterate ();
|
||||||
indentDepth--;
|
indentDepth--;
|
||||||
|
|
||||||
|
goal_unbind (b);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -906,7 +909,6 @@ bind_existing_to_goal (const Binding b, const int run, const int index)
|
|||||||
semiRunDestroy ();
|
semiRunDestroy ();
|
||||||
newruns--;
|
newruns--;
|
||||||
}
|
}
|
||||||
goal_unbind (b);
|
|
||||||
|
|
||||||
indentDepth--;
|
indentDepth--;
|
||||||
return flag;
|
return flag;
|
||||||
@ -1099,17 +1101,17 @@ bind_old_goal (const Binding b_new)
|
|||||||
if (b_old->done && isTermEqual (b_new->term, b_old->term))
|
if (b_old->done && isTermEqual (b_new->term, b_old->term))
|
||||||
{
|
{
|
||||||
// Old is done and has the same term!
|
// Old is done and has the same term!
|
||||||
// So we copy this binding, and fix it.
|
// So we try to copy this binding, and fix it.
|
||||||
b_new->run_from = b_old->run_from;
|
if (goal_bind (b_new, b_old->run_from, b_old->ev_from))
|
||||||
b_new->ev_from = b_old->ev_from;
|
{
|
||||||
b_new->done = 1;
|
return true;
|
||||||
return 1;
|
}
|
||||||
}
|
}
|
||||||
bl = bl->next;
|
bl = bl->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// No old binding to connect to
|
// No old binding to connect to
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Create a new intruder run to generate knowledge from m0
|
//! Create a new intruder run to generate knowledge from m0
|
||||||
@ -1154,12 +1156,12 @@ bind_goal_new_m0 (const Binding b)
|
|||||||
eprintf (" from the initial knowledge.\n");
|
eprintf (" from the initial knowledge.\n");
|
||||||
}
|
}
|
||||||
flag = flag && iterate ();
|
flag = flag && iterate ();
|
||||||
|
goal_unbind (b);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
proof_cannot_bind (b, run, 0);
|
proof_cannot_bind (b, run, 0);
|
||||||
}
|
}
|
||||||
goal_unbind (b);
|
|
||||||
indentDepth--;
|
indentDepth--;
|
||||||
}
|
}
|
||||||
semiRunDestroy ();
|
semiRunDestroy ();
|
||||||
@ -1247,12 +1249,12 @@ bind_goal_new_encrypt (const Binding b)
|
|||||||
{
|
{
|
||||||
proof_suppose_binding (b);
|
proof_suppose_binding (b);
|
||||||
flag = flag && iterate ();
|
flag = flag && iterate ();
|
||||||
|
goal_unbind (b);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
proof_cannot_bind (b, run, index);
|
proof_cannot_bind (b, run, index);
|
||||||
}
|
}
|
||||||
goal_unbind (b);
|
|
||||||
indentDepth--;
|
indentDepth--;
|
||||||
goal_remove_last (newgoals);
|
goal_remove_last (newgoals);
|
||||||
semiRunDestroy ();
|
semiRunDestroy ();
|
||||||
@ -1475,7 +1477,7 @@ bind_goal (const Binding b)
|
|||||||
flag = flag && iterate ();
|
flag = flag && iterate ();
|
||||||
|
|
||||||
// Unbind again
|
// Unbind again
|
||||||
b->done = 0;
|
goal_unbind (b);
|
||||||
indentDepth--;
|
indentDepth--;
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
@ -2215,7 +2217,6 @@ knowledgeAtArachne (const System sys, const int myrun, const int myindex,
|
|||||||
Knowledge know;
|
Knowledge know;
|
||||||
int run;
|
int run;
|
||||||
|
|
||||||
goal_graph_create (); // ensure a valid ordering graph
|
|
||||||
know = knowledgeDuplicate (sys->know); // duplicate initial knowledge
|
know = knowledgeDuplicate (sys->know); // duplicate initial knowledge
|
||||||
run = 0;
|
run = 0;
|
||||||
while (run < sys->maxruns)
|
while (run < sys->maxruns)
|
||||||
@ -2236,7 +2237,7 @@ knowledgeAtArachne (const System sys, const int myrun, const int myindex,
|
|||||||
while (rd != NULL && index < maxheight)
|
while (rd != NULL && index < maxheight)
|
||||||
{
|
{
|
||||||
// Check whether this event precedes myevent
|
// Check whether this event precedes myevent
|
||||||
if (aftercomplete || isOrderedBefore (run, index, myrun, myindex))
|
if (aftercomplete || isDependEvent (run, index, myrun, myindex))
|
||||||
{
|
{
|
||||||
// If it is a send (trivial) or a read (remarkable, but true
|
// If it is a send (trivial) or a read (remarkable, but true
|
||||||
// because of bindings) we can add the message and the agents to
|
// because of bindings) we can add the message and the agents to
|
||||||
|
@ -92,7 +92,7 @@ attackMinimize (const System sys, struct tracebuf *tb)
|
|||||||
}
|
}
|
||||||
if (i == tb->length)
|
if (i == tb->length)
|
||||||
{
|
{
|
||||||
printf ("Some step error.\n");
|
eprintf ("Some step error.\n");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ attackMinimize (const System sys, struct tracebuf *tb)
|
|||||||
}
|
}
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
{
|
{
|
||||||
printf ("Some i<0 error.\n");
|
eprintf ("Some i<0 error.\n");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
659
src/binding.c
659
src/binding.c
@ -14,22 +14,14 @@
|
|||||||
#include "termmap.h"
|
#include "termmap.h"
|
||||||
#include "arachne.h"
|
#include "arachne.h"
|
||||||
#include "switches.h"
|
#include "switches.h"
|
||||||
|
#include "depend.h"
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
static System sys; //!< local storage of system pointer
|
static System sys; //!< local storage of system pointer
|
||||||
int *graph = NULL; //!< graph data
|
|
||||||
int nodes = 0; //!< number of nodes in the graph
|
|
||||||
int graph_uordblks = 0;
|
|
||||||
|
|
||||||
extern Protocol INTRUDER; //!< The intruder protocol
|
extern Protocol INTRUDER; //!< The intruder protocol
|
||||||
extern Role I_M; //!< special role; precedes all other events always
|
extern Role I_M; //!< special role; precedes all other events always
|
||||||
|
|
||||||
/*
|
|
||||||
* Forward declarations
|
|
||||||
*/
|
|
||||||
|
|
||||||
void goal_graph_destroy ();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Assist stuff
|
* Assist stuff
|
||||||
@ -43,13 +35,12 @@ binding_create (Term term, int run_to, int ev_to)
|
|||||||
Binding b;
|
Binding b;
|
||||||
|
|
||||||
b = memAlloc (sizeof (struct binding));
|
b = memAlloc (sizeof (struct binding));
|
||||||
b->done = 0;
|
b->done = false;
|
||||||
b->blocked = 0;
|
b->blocked = false;
|
||||||
b->run_from = -1;
|
b->run_from = -1;
|
||||||
b->ev_from = -1;
|
b->ev_from = -1;
|
||||||
b->run_to = run_to;
|
b->run_to = run_to;
|
||||||
b->ev_to = ev_to;
|
b->ev_to = ev_to;
|
||||||
goal_graph_destroy ();
|
|
||||||
b->term = term;
|
b->term = term;
|
||||||
b->level = 0;
|
b->level = 0;
|
||||||
return b;
|
return b;
|
||||||
@ -66,17 +57,6 @@ binding_destroy (Binding b)
|
|||||||
memFree (b, sizeof (struct binding));
|
memFree (b, sizeof (struct binding));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Test whether one event is ordered before another
|
|
||||||
/**
|
|
||||||
* Is only guaranteed to yield trustworthy results after a new graph is created, using
|
|
||||||
* goal_graph_create ()
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
isOrderedBefore (const int run1, const int ev1, const int run2, const int ev2)
|
|
||||||
{
|
|
||||||
return graph[graph_nodes (nodes, run2, ev2, run2, ev2)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Main
|
* Main
|
||||||
@ -89,9 +69,8 @@ bindingInit (const System mysys)
|
|||||||
{
|
{
|
||||||
sys = mysys;
|
sys = mysys;
|
||||||
sys->bindings = NULL;
|
sys->bindings = NULL;
|
||||||
graph = NULL;
|
|
||||||
nodes = 0;
|
dependInit (sys);
|
||||||
graph_uordblks = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Close up
|
//! Close up
|
||||||
@ -101,262 +80,12 @@ bindingDone ()
|
|||||||
int delete (Binding b)
|
int delete (Binding b)
|
||||||
{
|
{
|
||||||
binding_destroy (b);
|
binding_destroy (b);
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
list_iterate (sys->bindings, delete);
|
list_iterate (sys->bindings, delete);
|
||||||
list_destroy (sys->bindings);
|
list_destroy (sys->bindings);
|
||||||
}
|
|
||||||
|
|
||||||
//! Destroy graph
|
dependDone (sys);
|
||||||
void
|
|
||||||
goal_graph_destroy ()
|
|
||||||
{
|
|
||||||
if (graph != NULL)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
struct mallinfo mi_free;
|
|
||||||
int mem_free;
|
|
||||||
|
|
||||||
mi_free = mallinfo ();
|
|
||||||
mem_free = mi_free.uordblks;
|
|
||||||
#endif
|
|
||||||
memFree (graph, (nodes * nodes) * sizeof (int));
|
|
||||||
graph = NULL;
|
|
||||||
#ifdef DEBUG
|
|
||||||
mi_free = mallinfo ();
|
|
||||||
if (mem_free - mi_free.uordblks != graph_uordblks)
|
|
||||||
error ("Freeing gave a weird result.");
|
|
||||||
#endif
|
|
||||||
graph_uordblks = 0;
|
|
||||||
nodes = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Compute unclosed graph
|
|
||||||
void
|
|
||||||
goal_graph_create ()
|
|
||||||
{
|
|
||||||
int run, ev;
|
|
||||||
int last_m;
|
|
||||||
List bl;
|
|
||||||
|
|
||||||
goal_graph_destroy ();
|
|
||||||
|
|
||||||
// Setup graph
|
|
||||||
nodes = node_count ();
|
|
||||||
|
|
||||||
{
|
|
||||||
struct mallinfo create_mi;
|
|
||||||
int create_mem_before;
|
|
||||||
|
|
||||||
if (graph_uordblks != 0)
|
|
||||||
error
|
|
||||||
("Trying to create graph stuff without 0 uordblks for it first, but it is %i.",
|
|
||||||
graph_uordblks);
|
|
||||||
create_mi = mallinfo ();
|
|
||||||
create_mem_before = create_mi.uordblks;
|
|
||||||
graph = memAlloc ((nodes * nodes) * sizeof (int));
|
|
||||||
create_mi = mallinfo ();
|
|
||||||
graph_uordblks = create_mi.uordblks - create_mem_before;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
graph_fill (graph, nodes, 0);
|
|
||||||
|
|
||||||
// Setup run order
|
|
||||||
run = 0;
|
|
||||||
last_m = -1; // last I_M run
|
|
||||||
while (run < sys->maxruns)
|
|
||||||
{
|
|
||||||
ev = 1;
|
|
||||||
//!@todo This now reference to step, but we intend "length" as in Arachne.
|
|
||||||
while (ev < sys->runs[run].step)
|
|
||||||
{
|
|
||||||
graph[graph_nodes (nodes, run, ev - 1, run, ev)] = 1;
|
|
||||||
ev++;
|
|
||||||
}
|
|
||||||
// Enforce I_M ordering
|
|
||||||
if (sys->runs[run].protocol == INTRUDER && sys->runs[run].role == I_M)
|
|
||||||
{
|
|
||||||
if (last_m != -1)
|
|
||||||
{
|
|
||||||
graph[graph_nodes (nodes, last_m, 0, run, 0)] = 1;
|
|
||||||
}
|
|
||||||
last_m = run;
|
|
||||||
}
|
|
||||||
// Next
|
|
||||||
run++;
|
|
||||||
}
|
|
||||||
// Setup bindings order
|
|
||||||
bl = sys->bindings;
|
|
||||||
while (bl != NULL)
|
|
||||||
{
|
|
||||||
Binding b;
|
|
||||||
|
|
||||||
b = (Binding) bl->data;
|
|
||||||
if (valid_binding (b))
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (graph_nodes
|
|
||||||
(nodes, b->run_from, b->ev_from, b->run_to,
|
|
||||||
b->ev_to) >= (nodes * nodes))
|
|
||||||
error ("Node out of scope for %i,%i -> %i,%i.\n", b->run_from,
|
|
||||||
b->ev_from, b->run_to, b->ev_to);
|
|
||||||
#endif
|
|
||||||
graph[graph_nodes
|
|
||||||
(nodes, b->run_from, b->ev_from, b->run_to, b->ev_to)] = 1;
|
|
||||||
}
|
|
||||||
bl = bl->next;
|
|
||||||
}
|
|
||||||
// Setup local constants order
|
|
||||||
run = 0;
|
|
||||||
while (run < sys->maxruns)
|
|
||||||
{
|
|
||||||
if (sys->runs[run].protocol != INTRUDER)
|
|
||||||
{
|
|
||||||
int run2;
|
|
||||||
|
|
||||||
run2 = 0;
|
|
||||||
while (run2 < sys->maxruns)
|
|
||||||
{
|
|
||||||
if (sys->runs[run].protocol != INTRUDER && run != run2)
|
|
||||||
{
|
|
||||||
// For these two runs, we check whether run has any variables that are mapped
|
|
||||||
// to constants from run2
|
|
||||||
Termlist tl;
|
|
||||||
|
|
||||||
tl = sys->runs[run].locals;
|
|
||||||
while (tl != NULL)
|
|
||||||
{
|
|
||||||
Term t;
|
|
||||||
|
|
||||||
t = tl->term;
|
|
||||||
if (t->type == VARIABLE && TermRunid (t) == run
|
|
||||||
&& t->subst != NULL)
|
|
||||||
{
|
|
||||||
// t is a variable of run
|
|
||||||
Termlist tl2;
|
|
||||||
|
|
||||||
tl2 = sys->runs[run2].locals;
|
|
||||||
while (tl2 != NULL)
|
|
||||||
{
|
|
||||||
Term t2;
|
|
||||||
|
|
||||||
t2 = tl2->term;
|
|
||||||
if (realTermLeaf (t2) && t2->type != VARIABLE
|
|
||||||
&& TermRunid (t2) == run2)
|
|
||||||
{
|
|
||||||
// t2 is a constant of run2
|
|
||||||
if (isTermEqual (t, t2))
|
|
||||||
{
|
|
||||||
// Indeed, run depends on the run2 constant t2. Thus we must store this order.
|
|
||||||
// The first send of t2 in run2 must be before the first (read) event in run with t2.
|
|
||||||
int ev2;
|
|
||||||
int done;
|
|
||||||
Roledef rd2;
|
|
||||||
|
|
||||||
done = 0;
|
|
||||||
ev2 = 0;
|
|
||||||
rd2 = sys->runs[run2].start;
|
|
||||||
while (!done
|
|
||||||
&& ev2 < sys->runs[run2].step)
|
|
||||||
{
|
|
||||||
if (rd2->type == SEND
|
|
||||||
&& termSubTerm (rd2->message,
|
|
||||||
t2))
|
|
||||||
{
|
|
||||||
// Allright, we send it here at ev2 first
|
|
||||||
int ev;
|
|
||||||
Roledef rd;
|
|
||||||
|
|
||||||
ev = 0;
|
|
||||||
rd = sys->runs[run].start;
|
|
||||||
while (!done
|
|
||||||
&& ev <
|
|
||||||
sys->runs[run].step)
|
|
||||||
{
|
|
||||||
if (termSubTerm
|
|
||||||
(rd->message, t2))
|
|
||||||
{
|
|
||||||
// Term occurs here in run
|
|
||||||
if (rd->type == READ)
|
|
||||||
{
|
|
||||||
// It's read here first.
|
|
||||||
// Order and be done with it.
|
|
||||||
graph[graph_nodes
|
|
||||||
(nodes,
|
|
||||||
run2, ev2,
|
|
||||||
run, ev)] =
|
|
||||||
1;
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (DEBUGL (5))
|
|
||||||
{
|
|
||||||
eprintf
|
|
||||||
("* [local originator] term ");
|
|
||||||
termPrint
|
|
||||||
(t2);
|
|
||||||
eprintf
|
|
||||||
(" is bound using %i, %i before %i,%i\n",
|
|
||||||
run2, ev2,
|
|
||||||
run, ev);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
done = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// It doesn't occur first in a READ, which shouldn't be happening
|
|
||||||
if (switches.
|
|
||||||
output ==
|
|
||||||
PROOF)
|
|
||||||
{
|
|
||||||
eprintf
|
|
||||||
("Term ");
|
|
||||||
termPrint
|
|
||||||
(t2);
|
|
||||||
eprintf
|
|
||||||
(" from run %i occurs in run %i, term ",
|
|
||||||
run2, run);
|
|
||||||
termPrint (t);
|
|
||||||
eprintf
|
|
||||||
(" before it is read?\n");
|
|
||||||
}
|
|
||||||
// Thus, we create an artificial loop
|
|
||||||
if (sys->runs[0].
|
|
||||||
step > 1)
|
|
||||||
{
|
|
||||||
// This forces a loop, and thus prunes
|
|
||||||
graph
|
|
||||||
[graph_nodes
|
|
||||||
(nodes, 0,
|
|
||||||
1, 0,
|
|
||||||
0)] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rd = rd->next;
|
|
||||||
ev++;
|
|
||||||
}
|
|
||||||
done = 1;
|
|
||||||
}
|
|
||||||
rd2 = rd2->next;
|
|
||||||
ev2++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tl2 = tl2->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tl = tl->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
run2++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
run++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -366,67 +95,6 @@ goal_graph_create ()
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//! Yield node count
|
|
||||||
int
|
|
||||||
node_count ()
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
int run;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
for (run = 0; run < sys->maxruns; run++)
|
|
||||||
{
|
|
||||||
//!@todo This now reference to step, but we intend "length" as in Arachne.
|
|
||||||
count = count + sys->runs[run].step;
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Yield node number given run, ev
|
|
||||||
__inline__ int
|
|
||||||
node_number (int run, int ev)
|
|
||||||
{
|
|
||||||
int node;
|
|
||||||
|
|
||||||
node = ev;
|
|
||||||
while (run > 0)
|
|
||||||
{
|
|
||||||
run--;
|
|
||||||
//!@todo This now reference to step, but we intend "length" as in Arachne.
|
|
||||||
node = node + sys->runs[run].step;
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Yield graph index, given node1, node2 numbers
|
|
||||||
__inline__ int
|
|
||||||
graph_index (const int node1, const int node2)
|
|
||||||
{
|
|
||||||
return ((node1 * nodes) + node2);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Yield graph index, given (node1), (node2) tuples
|
|
||||||
__inline__ int
|
|
||||||
graph_nodes (const int nodes, const int run1, const int ev1, const int run2,
|
|
||||||
const int ev2)
|
|
||||||
{
|
|
||||||
int node1;
|
|
||||||
int node2;
|
|
||||||
|
|
||||||
node1 = node_number (run1, ev1);
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (node1 < 0 || node1 >= nodes)
|
|
||||||
error ("node_number %i out of scope %i for %i,%i.", node1, nodes, run1,
|
|
||||||
ev1);
|
|
||||||
#endif
|
|
||||||
node2 = node_number (run2, ev2);
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (node2 < 0 || node2 >= nodes)
|
|
||||||
error ("node_number %i out of scope %i for %i,%i.", node2, nodes, run2,
|
|
||||||
ev2);
|
|
||||||
#endif
|
|
||||||
return graph_index (node1, node2);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Print a binding (given a binding list pointer)
|
//! Print a binding (given a binding list pointer)
|
||||||
int
|
int
|
||||||
@ -440,7 +108,86 @@ binding_print (const Binding b)
|
|||||||
eprintf (" )->> (%i,%i)", b->run_to, b->ev_to);
|
eprintf (" )->> (%i,%i)", b->run_to, b->ev_to);
|
||||||
if (b->blocked)
|
if (b->blocked)
|
||||||
eprintf ("[blocked]");
|
eprintf ("[blocked]");
|
||||||
return 1;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Bind a goal (true if success, false if it must be pruned)
|
||||||
|
int
|
||||||
|
goal_bind (const Binding b, const int run, const int ev)
|
||||||
|
{
|
||||||
|
if (b->blocked)
|
||||||
|
{
|
||||||
|
error ("Trying to bind a blocked goal.");
|
||||||
|
}
|
||||||
|
if (!b->done)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (run >= sys->maxruns || sys->runs[run].step <= ev)
|
||||||
|
error ("Trying to bind to something not yet in the semistate.");
|
||||||
|
#endif
|
||||||
|
b->run_from = run;
|
||||||
|
b->ev_from = ev;
|
||||||
|
if (dependPushEvent (run, ev, b->run_to, b->ev_to))
|
||||||
|
{
|
||||||
|
b->done = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
globalError++;
|
||||||
|
binding_print (b);
|
||||||
|
error ("Trying to bind a bound goal again.");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Unbind a goal
|
||||||
|
void
|
||||||
|
goal_unbind (const Binding b)
|
||||||
|
{
|
||||||
|
if (b->done)
|
||||||
|
{
|
||||||
|
dependPopEvent ();
|
||||||
|
b->done = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error ("Trying to unbind an unbound goal again.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Bind a goal as a dummy (block)
|
||||||
|
/**
|
||||||
|
* Especially made for tuple expansion
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
binding_block (Binding b)
|
||||||
|
{
|
||||||
|
if (!b->blocked)
|
||||||
|
{
|
||||||
|
b->blocked = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error ("Trying to block a goal again.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Unblock a binding
|
||||||
|
int
|
||||||
|
binding_unblock (Binding b)
|
||||||
|
{
|
||||||
|
if (b->blocked)
|
||||||
|
{
|
||||||
|
b->blocked = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error ("Trying to unblock a non-blocked goal.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -448,6 +195,8 @@ binding_print (const Binding b)
|
|||||||
/**
|
/**
|
||||||
* The int parameter 'level' is just to store additional info. Here, it stores priorities for a goal.
|
* The int parameter 'level' is just to store additional info. Here, it stores priorities for a goal.
|
||||||
* Higher level goals will be selected first. Typically, a normal goal is level 0, a key is 1.
|
* Higher level goals will be selected first. Typically, a normal goal is level 0, a key is 1.
|
||||||
|
*
|
||||||
|
* Returns the number of added goals (sometimes unfolding tuples)
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
goal_add (Term term, const int run, const int ev, const int level)
|
goal_add (Term term, const int run, const int ev, const int level)
|
||||||
@ -479,11 +228,11 @@ goal_add (Term term, const int run, const int ev, const int level)
|
|||||||
b = (Binding) data;
|
b = (Binding) data;
|
||||||
if (isTermEqual (b->term, term) && run == b->run_to && ev == b->ev_to)
|
if (isTermEqual (b->term, term) && run == b->run_to && ev == b->ev_to)
|
||||||
{ // abort scan, report
|
{ // abort scan, report
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // proceed with scan
|
{ // proceed with scan
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,46 +258,6 @@ goal_add (Term term, const int run, const int ev, const int level)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Add a goal, and bind it immediately.
|
|
||||||
// If the result is negative, no goals will have been added, as the resulting state must be pruned (cycle) */
|
|
||||||
int
|
|
||||||
goal_add_fixed (Term term, const int run, const int ev, const int fromrun,
|
|
||||||
const int fromev)
|
|
||||||
{
|
|
||||||
int newgoals, n;
|
|
||||||
List l;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
newgoals = goal_add (term, run, ev, 0);
|
|
||||||
l = sys->bindings;
|
|
||||||
n = newgoals;
|
|
||||||
res = 1;
|
|
||||||
while (res != 0 && n > 0 && l != NULL)
|
|
||||||
{
|
|
||||||
Binding b;
|
|
||||||
|
|
||||||
b = (Binding) l->data;
|
|
||||||
if (b->done)
|
|
||||||
{
|
|
||||||
globalError++;
|
|
||||||
binding_print (b);
|
|
||||||
error (" problem with new fixed binding!");
|
|
||||||
}
|
|
||||||
res = goal_bind (b, fromrun, fromev); // returns 0 if it must be pruned
|
|
||||||
l = l->next;
|
|
||||||
n--;
|
|
||||||
}
|
|
||||||
if (res != 0)
|
|
||||||
{
|
|
||||||
return newgoals;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
goal_remove_last (newgoals);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Remove a goal
|
//! Remove a goal
|
||||||
void
|
void
|
||||||
goal_remove_last (int n)
|
goal_remove_last (int n)
|
||||||
@ -573,82 +282,6 @@ goal_remove_last (int n)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Bind a goal (0 if it must be pruned)
|
|
||||||
int
|
|
||||||
goal_bind (const Binding b, const int run, const int ev)
|
|
||||||
{
|
|
||||||
if (b->blocked)
|
|
||||||
{
|
|
||||||
error ("Trying to bind a blocked goal.");
|
|
||||||
}
|
|
||||||
if (!b->done)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (run >= sys->maxruns || sys->runs[run].step <= ev)
|
|
||||||
error ("Trying to bind to something not yet in the semistate.");
|
|
||||||
#endif
|
|
||||||
b->done = 1;
|
|
||||||
b->run_from = run;
|
|
||||||
b->ev_from = ev;
|
|
||||||
goal_graph_create ();
|
|
||||||
return warshall (graph, nodes);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
globalError++;
|
|
||||||
binding_print (b);
|
|
||||||
error ("Trying to bind a bound goal again.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Unbind a goal
|
|
||||||
void
|
|
||||||
goal_unbind (const Binding b)
|
|
||||||
{
|
|
||||||
if (b->done)
|
|
||||||
{
|
|
||||||
goal_graph_destroy (b);
|
|
||||||
b->done = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
error ("Trying to unbind an unbound goal again.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Bind a goal as a dummy (block)
|
|
||||||
/**
|
|
||||||
* Especially made for tuple expansion
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
binding_block (Binding b)
|
|
||||||
{
|
|
||||||
if (!b->blocked)
|
|
||||||
{
|
|
||||||
b->blocked = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
error ("Trying to block a goal again.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Unblock a binding
|
|
||||||
int
|
|
||||||
binding_unblock (Binding b)
|
|
||||||
{
|
|
||||||
if (b->blocked)
|
|
||||||
{
|
|
||||||
b->blocked = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
error ("Trying to unblock a non-blocked goal.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Determine whether some label set is ordered w.r.t. send/read order.
|
//! Determine whether some label set is ordered w.r.t. send/read order.
|
||||||
/**
|
/**
|
||||||
* Assumes all these labels exist in the system, within length etc, and that the run mappings are valid.
|
* Assumes all these labels exist in the system, within length etc, and that the run mappings are valid.
|
||||||
@ -656,12 +289,6 @@ binding_unblock (Binding b)
|
|||||||
int
|
int
|
||||||
labels_ordered (Termmap runs, Termlist labels)
|
labels_ordered (Termmap runs, Termlist labels)
|
||||||
{
|
{
|
||||||
goal_graph_create ();
|
|
||||||
if (warshall (graph, nodes) == 0)
|
|
||||||
{
|
|
||||||
error ("Testing ordering of label set for a graph with a cycle.");
|
|
||||||
}
|
|
||||||
|
|
||||||
while (labels != NULL)
|
while (labels != NULL)
|
||||||
{
|
{
|
||||||
// Given this label, and the mapping of runs, we want to know if the order is okay. Thus, we need to know sendrole and readrole
|
// Given this label, and the mapping of runs, we want to know if the order is okay. Thus, we need to know sendrole and readrole
|
||||||
@ -693,17 +320,16 @@ labels_ordered (Termmap runs, Termlist labels)
|
|||||||
read_run = termmapGet (runs, linfo->readrole);
|
read_run = termmapGet (runs, linfo->readrole);
|
||||||
send_ev = get_index (send_run);
|
send_ev = get_index (send_run);
|
||||||
read_ev = get_index (read_run);
|
read_ev = get_index (read_run);
|
||||||
if (graph[graph_nodes (nodes, send_run, send_ev, read_run, read_ev)] ==
|
if (!isDependEvent (send_run, send_ev, read_run, read_ev))
|
||||||
0)
|
|
||||||
{
|
{
|
||||||
// Not ordered; false
|
// Not ordered; false
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Proceed
|
// Proceed
|
||||||
labels = labels->next;
|
labels = labels->next;
|
||||||
}
|
}
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Check whether the binding denotes a sensible thing such that we can use run_from and ev_from
|
//! Check whether the binding denotes a sensible thing such that we can use run_from and ev_from
|
||||||
@ -711,9 +337,9 @@ int
|
|||||||
valid_binding (Binding b)
|
valid_binding (Binding b)
|
||||||
{
|
{
|
||||||
if (b->done && !b->blocked)
|
if (b->done && !b->blocked)
|
||||||
return 1;
|
return true;
|
||||||
else
|
else
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Check for unique origination
|
//! Check for unique origination
|
||||||
@ -774,7 +400,7 @@ unique_origination ()
|
|||||||
b->ev_from != b2->ev_from)
|
b->ev_from != b2->ev_from)
|
||||||
{
|
{
|
||||||
// Not equal: thus no unique origination.
|
// Not equal: thus no unique origination.
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
termlistDelete (terms2);
|
termlistDelete (terms2);
|
||||||
@ -787,7 +413,7 @@ unique_origination ()
|
|||||||
}
|
}
|
||||||
bl = bl->next;
|
bl = bl->next;
|
||||||
}
|
}
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Prune invalid state w.r.t. <=C minimal requirement
|
//! Prune invalid state w.r.t. <=C minimal requirement
|
||||||
@ -799,92 +425,5 @@ unique_origination ()
|
|||||||
int
|
int
|
||||||
bindings_c_minimal ()
|
bindings_c_minimal ()
|
||||||
{
|
{
|
||||||
List bl;
|
return unique_origination ();
|
||||||
|
|
||||||
if (switches.experimental & 1 > 0)
|
|
||||||
{
|
|
||||||
if (unique_origination () == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure a fresh state graph
|
|
||||||
goal_graph_create ();
|
|
||||||
// Recompute closure; does that work?
|
|
||||||
if (!warshall (graph, nodes))
|
|
||||||
{
|
|
||||||
List l;
|
|
||||||
|
|
||||||
globalError++;
|
|
||||||
l = sys->bindings;
|
|
||||||
while (l != NULL)
|
|
||||||
{
|
|
||||||
Binding b;
|
|
||||||
|
|
||||||
b = (Binding) l->data;
|
|
||||||
binding_print (b);
|
|
||||||
eprintf ("\n");
|
|
||||||
l = l->next;
|
|
||||||
}
|
|
||||||
error ("Detected a cycle when testing for c-minimality");
|
|
||||||
}
|
|
||||||
|
|
||||||
// For all goals
|
|
||||||
bl = sys->bindings;
|
|
||||||
while (bl != NULL)
|
|
||||||
{
|
|
||||||
Binding b;
|
|
||||||
|
|
||||||
b = (Binding) bl->data;
|
|
||||||
// Check for a valid binding; it has to be 'done' and sensibly bound (not as in tuple expanded stuff)
|
|
||||||
if (valid_binding (b))
|
|
||||||
{
|
|
||||||
int run;
|
|
||||||
int node_from;
|
|
||||||
|
|
||||||
node_from = node_number (b->run_from, b->ev_from);
|
|
||||||
// Find all preceding events
|
|
||||||
for (run = 0; run < sys->maxruns; run++)
|
|
||||||
{
|
|
||||||
int ev;
|
|
||||||
|
|
||||||
//!@todo hardcoded reference to step, should be length
|
|
||||||
for (ev = 0; ev < sys->runs[run].step; ev++)
|
|
||||||
{
|
|
||||||
int node_comp;
|
|
||||||
|
|
||||||
node_comp = node_number (run, ev);
|
|
||||||
if (graph[graph_index (node_comp, node_from)] > 0)
|
|
||||||
{
|
|
||||||
// this node is *before* the from node
|
|
||||||
Roledef rd;
|
|
||||||
|
|
||||||
rd = roledef_shift (sys->runs[run].start, ev);
|
|
||||||
if (termInTerm (rd->message, b->term))
|
|
||||||
{
|
|
||||||
// This term already occurs as interm in a previous node!
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (DEBUGL (4))
|
|
||||||
{
|
|
||||||
// Report this
|
|
||||||
indentPrint ();
|
|
||||||
eprintf ("Binding for ");
|
|
||||||
termPrint (b->term);
|
|
||||||
eprintf
|
|
||||||
(" at r%i i%i is not c-minimal because it occurred before at r%i i%i in ",
|
|
||||||
b->run_from, b->ev_from, run, ev);
|
|
||||||
termPrint (rd->message);
|
|
||||||
eprintf ("\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bl = bl->next;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
@ -30,17 +30,6 @@ typedef struct binding *Binding; //!< pointer to binding structure
|
|||||||
void bindingInit (const System mysys);
|
void bindingInit (const System mysys);
|
||||||
void bindingDone ();
|
void bindingDone ();
|
||||||
|
|
||||||
int node_count ();
|
|
||||||
int node_number (int run, int ev);
|
|
||||||
__inline__ int graph_nodes (const int nodes, const int run1, const int ev1,
|
|
||||||
const int run2, const int ev2);
|
|
||||||
|
|
||||||
int isOrderedBefore (const int run1, const int ev1, const int run2,
|
|
||||||
const int ev2);
|
|
||||||
|
|
||||||
void goal_graph_create ();
|
|
||||||
|
|
||||||
|
|
||||||
int binding_print (Binding b);
|
int binding_print (Binding b);
|
||||||
int valid_binding (Binding b);
|
int valid_binding (Binding b);
|
||||||
|
|
||||||
|
55
src/claim.c
55
src/claim.c
@ -57,7 +57,7 @@ indact ()
|
|||||||
i = indac;
|
i = indac;
|
||||||
while (i > 0)
|
while (i > 0)
|
||||||
{
|
{
|
||||||
printf ("| ");
|
eprintf ("| ");
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,10 +136,10 @@ oki_nisynch_full (const System sys, const Termmap label_to_index)
|
|||||||
{
|
{
|
||||||
#ifdef OKIDEBUG
|
#ifdef OKIDEBUG
|
||||||
indact ();
|
indact ();
|
||||||
printf ("Incorrectly linked label at the end,");
|
eprintf ("Incorrectly linked label at the end,");
|
||||||
printf ("label: ");
|
eprintf ("label: ");
|
||||||
termPrint (label_to_index_scan->term);
|
termPrint (label_to_index_scan->term);
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -158,13 +158,13 @@ oki_nisynch_other (const System sys, const int trace_index,
|
|||||||
|
|
||||||
#ifdef OKIDEBUG
|
#ifdef OKIDEBUG
|
||||||
indact ();
|
indact ();
|
||||||
printf ("Exploring further assuming this (claim) run is not involved.\n");
|
eprintf ("Exploring further assuming this (claim) run is not involved.\n");
|
||||||
indac++;
|
indac++;
|
||||||
#endif
|
#endif
|
||||||
result = oki_nisynch (sys, trace_index - 1, role_to_run, label_to_index);
|
result = oki_nisynch (sys, trace_index - 1, role_to_run, label_to_index);
|
||||||
#ifdef OKIDEBUG
|
#ifdef OKIDEBUG
|
||||||
indact ();
|
indact ();
|
||||||
printf (">%i<\n", result);
|
eprintf (">%i<\n", result);
|
||||||
indac--;
|
indac--;
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
@ -202,7 +202,7 @@ oki_nisynch_read (const System sys, const int trace_index,
|
|||||||
termmapSet (label_to_index_buf, rd->label, trace_index);
|
termmapSet (label_to_index_buf, rd->label, trace_index);
|
||||||
#ifdef OKIDEBUG
|
#ifdef OKIDEBUG
|
||||||
indact ();
|
indact ();
|
||||||
printf ("Exploring because this (read) run is involved.\n");
|
eprintf ("Exploring because this (read) run is involved.\n");
|
||||||
indac++;
|
indac++;
|
||||||
#endif
|
#endif
|
||||||
result =
|
result =
|
||||||
@ -210,7 +210,7 @@ oki_nisynch_read (const System sys, const int trace_index,
|
|||||||
label_to_index_buf);
|
label_to_index_buf);
|
||||||
#ifdef OKIDEBUG
|
#ifdef OKIDEBUG
|
||||||
indact ();
|
indact ();
|
||||||
printf (">%i<\n", result);
|
eprintf (">%i<\n", result);
|
||||||
indac--;
|
indac--;
|
||||||
#endif
|
#endif
|
||||||
termmapDelete (label_to_index_buf);
|
termmapDelete (label_to_index_buf);
|
||||||
@ -222,7 +222,7 @@ oki_nisynch_read (const System sys, const int trace_index,
|
|||||||
// Apparently not involved
|
// Apparently not involved
|
||||||
#ifdef OKIDEBUG
|
#ifdef OKIDEBUG
|
||||||
indact ();
|
indact ();
|
||||||
printf ("Exploring further assuming this (read) run is not involved.\n");
|
eprintf ("Exploring further assuming this (read) run is not involved.\n");
|
||||||
indac++;
|
indac++;
|
||||||
#endif
|
#endif
|
||||||
result = oki_nisynch (sys, trace_index - 1, role_to_run, label_to_index);
|
result = oki_nisynch (sys, trace_index - 1, role_to_run, label_to_index);
|
||||||
@ -252,13 +252,14 @@ oki_nisynch_send (const System sys, const int trace_index,
|
|||||||
// 1. Assume that this run is not yet involved
|
// 1. Assume that this run is not yet involved
|
||||||
#ifdef OKIDEBUG
|
#ifdef OKIDEBUG
|
||||||
indact ();
|
indact ();
|
||||||
printf ("Exploring further assuming (send) run %i is not involved.\n", rid);
|
eprintf ("Exploring further assuming (send) run %i is not involved.\n",
|
||||||
|
rid);
|
||||||
indac++;
|
indac++;
|
||||||
#endif
|
#endif
|
||||||
result = oki_nisynch (sys, trace_index - 1, role_to_run, label_to_index);
|
result = oki_nisynch (sys, trace_index - 1, role_to_run, label_to_index);
|
||||||
#ifdef OKIDEBUG
|
#ifdef OKIDEBUG
|
||||||
indact ();
|
indact ();
|
||||||
printf (">%i<\n", result);
|
eprintf (">%i<\n", result);
|
||||||
indac--;
|
indac--;
|
||||||
#endif
|
#endif
|
||||||
if (result)
|
if (result)
|
||||||
@ -266,7 +267,7 @@ oki_nisynch_send (const System sys, const int trace_index,
|
|||||||
|
|
||||||
#ifdef OKIDEBUG
|
#ifdef OKIDEBUG
|
||||||
indact ();
|
indact ();
|
||||||
printf ("Exploring when %i is involved.\n", rid);
|
eprintf ("Exploring when %i is involved.\n", rid);
|
||||||
#endif
|
#endif
|
||||||
// 2. It is involved. Then either already used for this role, or will be now.
|
// 2. It is involved. Then either already used for this role, or will be now.
|
||||||
rolename = sys->runs[rid].role->nameterm;
|
rolename = sys->runs[rid].role->nameterm;
|
||||||
@ -289,9 +290,9 @@ oki_nisynch_send (const System sys, const int trace_index,
|
|||||||
|
|
||||||
#ifdef OKIDEBUG
|
#ifdef OKIDEBUG
|
||||||
indact ();
|
indact ();
|
||||||
printf ("Matching messages found for label ");
|
eprintf ("Matching messages found for label ");
|
||||||
termPrint (rd->label);
|
termPrint (rd->label);
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
#endif
|
#endif
|
||||||
/**
|
/**
|
||||||
*@todo Optimization can be done when old_run == rid, no copy of role_to_run needs to be made.
|
*@todo Optimization can be done when old_run == rid, no copy of role_to_run needs to be made.
|
||||||
@ -303,10 +304,10 @@ oki_nisynch_send (const System sys, const int trace_index,
|
|||||||
termmapSet (label_to_index_buf, rd->label, LABEL_GOOD);
|
termmapSet (label_to_index_buf, rd->label, LABEL_GOOD);
|
||||||
#ifdef OKIDEBUG
|
#ifdef OKIDEBUG
|
||||||
indact ();
|
indact ();
|
||||||
printf ("In NI-Synch scan, assuming %i run is involved.\n",
|
eprintf ("In NI-Synch scan, assuming %i run is involved.\n",
|
||||||
rid);
|
rid);
|
||||||
indact ();
|
indact ();
|
||||||
printf
|
eprintf
|
||||||
("Exploring further assuming this matching, which worked.\n");
|
("Exploring further assuming this matching, which worked.\n");
|
||||||
indac++;
|
indac++;
|
||||||
#endif
|
#endif
|
||||||
@ -315,7 +316,7 @@ oki_nisynch_send (const System sys, const int trace_index,
|
|||||||
label_to_index_buf);
|
label_to_index_buf);
|
||||||
#ifdef OKIDEBUG
|
#ifdef OKIDEBUG
|
||||||
indact ();
|
indact ();
|
||||||
printf (">%i<\n", result);
|
eprintf (">%i<\n", result);
|
||||||
indac--;
|
indac--;
|
||||||
#endif
|
#endif
|
||||||
termmapDelete (label_to_index_buf);
|
termmapDelete (label_to_index_buf);
|
||||||
@ -348,10 +349,10 @@ oki_nisynch (const System sys, const int trace_index,
|
|||||||
|
|
||||||
#ifdef OKIDEBUG
|
#ifdef OKIDEBUG
|
||||||
indact ();
|
indact ();
|
||||||
printf ("Checking event %i", trace_index);
|
eprintf ("Checking event %i", trace_index);
|
||||||
printf (" = #%i : ", sys->traceRun[trace_index]);
|
eprintf (" = #%i : ", sys->traceRun[trace_index]);
|
||||||
roledefPrint (sys->traceEvent[trace_index]);
|
roledefPrint (sys->traceEvent[trace_index]);
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
type = sys->traceEvent[trace_index]->type;
|
type = sys->traceEvent[trace_index]->type;
|
||||||
@ -471,16 +472,16 @@ check_claim_niagree (const System sys, const int i)
|
|||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
warning ("Claim has failed!");
|
warning ("Claim has failed!");
|
||||||
printf ("To be exact, claim label ");
|
eprintf ("To be exact, claim label ");
|
||||||
termPrint (cl->label);
|
termPrint (cl->label);
|
||||||
printf (" with prec set ");
|
eprintf (" with prec set ");
|
||||||
termlistPrint (cl->prec);
|
termlistPrint (cl->prec);
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
printf ("i: %i\nf: ", i);
|
eprintf ("i: %i\nf: ", i);
|
||||||
termmapPrint (f);
|
termmapPrint (f);
|
||||||
printf ("\ng: ");
|
eprintf ("\ng: ");
|
||||||
termmapPrint (g);
|
termmapPrint (g);
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "switches.h"
|
#include "switches.h"
|
||||||
#include "specialterm.h"
|
#include "specialterm.h"
|
||||||
|
#include "warshall.h"
|
||||||
#include "hidelevel.h"
|
#include "hidelevel.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1304,8 +1305,9 @@ void
|
|||||||
compute_prec_sets (const System sys)
|
compute_prec_sets (const System sys)
|
||||||
{
|
{
|
||||||
Term *eventlabels; // array: maps events to labels
|
Term *eventlabels; // array: maps events to labels
|
||||||
int *prec; // array: maps event*event to precedence
|
unsigned int *prec; // array: maps event*event to precedence
|
||||||
int size; // temp constant: rolecount * roleeventmax
|
int size; // temp constant: rolecount * roleeventmax
|
||||||
|
int rowsize;
|
||||||
int r1, r2, ev1, ev2; // some counters
|
int r1, r2, ev1, ev2; // some counters
|
||||||
int i, j;
|
int i, j;
|
||||||
Claimlist cl;
|
Claimlist cl;
|
||||||
@ -1316,11 +1318,6 @@ compute_prec_sets (const System sys)
|
|||||||
return r * sys->roleeventmax + lev;
|
return r * sys->roleeventmax + lev;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assist: compute matrix index from i*i
|
|
||||||
int index2 (int i1, int i2)
|
|
||||||
{
|
|
||||||
return i1 * size + i2;
|
|
||||||
}
|
|
||||||
// Assist: yield roledef from r, lev
|
// Assist: yield roledef from r, lev
|
||||||
Roledef roledef_re (int r, int lev)
|
Roledef roledef_re (int r, int lev)
|
||||||
{
|
{
|
||||||
@ -1382,7 +1379,8 @@ compute_prec_sets (const System sys)
|
|||||||
while (ev2 < sys->roleeventmax)
|
while (ev2 < sys->roleeventmax)
|
||||||
{
|
{
|
||||||
eprintf ("%i ",
|
eprintf ("%i ",
|
||||||
prec[index2 (index (r2, ev2), index (r1, ev1))]);
|
BIT (prec + rowsize * index (r2, ev2),
|
||||||
|
index (r1, ev1)));
|
||||||
ev2++;
|
ev2++;
|
||||||
}
|
}
|
||||||
eprintf (" ");
|
eprintf (" ");
|
||||||
@ -1403,21 +1401,9 @@ compute_prec_sets (const System sys)
|
|||||||
//eprintf ("Rolecount: %i\n", sys->rolecount);
|
//eprintf ("Rolecount: %i\n", sys->rolecount);
|
||||||
//eprintf ("Maxevent : %i\n", sys->roleeventmax);
|
//eprintf ("Maxevent : %i\n", sys->roleeventmax);
|
||||||
size = sys->rolecount * sys->roleeventmax;
|
size = sys->rolecount * sys->roleeventmax;
|
||||||
|
rowsize = WORDSIZE (size);
|
||||||
eventlabels = memAlloc (size * sizeof (Term));
|
eventlabels = memAlloc (size * sizeof (Term));
|
||||||
prec = memAlloc (size * size * sizeof (int));
|
prec = (unsigned int *) CALLOC (1, rowsize * size * sizeof (unsigned int));
|
||||||
// Clear tables
|
|
||||||
i = 0;
|
|
||||||
while (i < size)
|
|
||||||
{
|
|
||||||
eventlabels[i] = NULL;
|
|
||||||
j = 0;
|
|
||||||
while (j < size)
|
|
||||||
{
|
|
||||||
prec[index2 (i, j)] = 0;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
// Assign labels
|
// Assign labels
|
||||||
r1 = 0;
|
r1 = 0;
|
||||||
while (r1 < sys->rolecount)
|
while (r1 < sys->rolecount)
|
||||||
@ -1444,7 +1430,7 @@ compute_prec_sets (const System sys)
|
|||||||
ev1 = 0;
|
ev1 = 0;
|
||||||
while (ev1 < (sys->roleeventmax - 1))
|
while (ev1 < (sys->roleeventmax - 1))
|
||||||
{
|
{
|
||||||
prec[index2 (index (r1, ev1), index (r1, ev1 + 1))] = 1;
|
SETBIT (prec + rowsize * index (r1, ev1), index (r1, ev1 + 1));
|
||||||
ev1++;
|
ev1++;
|
||||||
}
|
}
|
||||||
r1++;
|
r1++;
|
||||||
@ -1473,7 +1459,8 @@ compute_prec_sets (const System sys)
|
|||||||
if (rd2 != NULL && rd2->type == READ
|
if (rd2 != NULL && rd2->type == READ
|
||||||
&& isTermEqual (rd1->label, rd2->label))
|
&& isTermEqual (rd1->label, rd2->label))
|
||||||
{
|
{
|
||||||
prec[index2 (index (r1, ev1), index (r2, ev2))] = 1;
|
SETBIT (prec + rowsize * index (r1, ev1),
|
||||||
|
index (r2, ev2));
|
||||||
}
|
}
|
||||||
ev2++;
|
ev2++;
|
||||||
}
|
}
|
||||||
@ -1484,14 +1471,18 @@ compute_prec_sets (const System sys)
|
|||||||
}
|
}
|
||||||
r1++;
|
r1++;
|
||||||
}
|
}
|
||||||
//[x] show_matrix ();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compute transitive closure (Warshall).
|
* Compute transitive closure (Warshall).
|
||||||
*/
|
*/
|
||||||
warshall (prec, size);
|
transitive_closure (prec, size);
|
||||||
|
|
||||||
// [x] show_matrix ();
|
#ifdef DEBUG
|
||||||
|
if (DEBUGL (5))
|
||||||
|
{
|
||||||
|
show_matrix ();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Last phase: Process all individual claims
|
* Last phase: Process all individual claims
|
||||||
@ -1550,7 +1541,7 @@ compute_prec_sets (const System sys)
|
|||||||
rd = roledef_re (r2, ev2);
|
rd = roledef_re (r2, ev2);
|
||||||
while (rd != NULL)
|
while (rd != NULL)
|
||||||
{
|
{
|
||||||
if (prec[index2 (index (r2, ev2), claim_index)] == 1)
|
if (BIT (prec + rowsize * index (r2, ev2), claim_index))
|
||||||
{
|
{
|
||||||
// This event precedes the claim
|
// This event precedes the claim
|
||||||
|
|
||||||
@ -1620,8 +1611,9 @@ compute_prec_sets (const System sys)
|
|||||||
while (ev_scan < sys->roleeventmax)
|
while (ev_scan < sys->roleeventmax)
|
||||||
{
|
{
|
||||||
// if this event preceds the claim, replace the label term
|
// if this event preceds the claim, replace the label term
|
||||||
if (prec[index2 (index (r_scan, ev_scan), claim_index)]
|
if (BIT
|
||||||
== 1)
|
(prec + rowsize * index (r_scan, ev_scan),
|
||||||
|
claim_index))
|
||||||
{
|
{
|
||||||
Roledef rd;
|
Roledef rd;
|
||||||
|
|
||||||
@ -1699,7 +1691,7 @@ compute_prec_sets (const System sys)
|
|||||||
* Cleanup
|
* Cleanup
|
||||||
*/
|
*/
|
||||||
memFree (eventlabels, size * sizeof (Term));
|
memFree (eventlabels, size * sizeof (Term));
|
||||||
memFree (prec, size * size * sizeof (int));
|
FREE (prec);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (DEBUGL (2))
|
if (DEBUGL (2))
|
||||||
|
@ -173,7 +173,7 @@ constraintlistDelete (Constraintlist cl)
|
|||||||
if (cl->prev != NULL)
|
if (cl->prev != NULL)
|
||||||
{
|
{
|
||||||
/* TODO maybe this should cause a warning? */
|
/* TODO maybe this should cause a warning? */
|
||||||
printf ("WARNING: clDelete with non-empty prev\n");
|
eprintf ("WARNING: clDelete with non-empty prev\n");
|
||||||
cl->prev->next = NULL;
|
cl->prev->next = NULL;
|
||||||
}
|
}
|
||||||
while (cl != NULL)
|
while (cl != NULL)
|
||||||
@ -198,7 +198,7 @@ constraintlistDestroy (Constraintlist cl)
|
|||||||
if (cl->prev != NULL)
|
if (cl->prev != NULL)
|
||||||
{
|
{
|
||||||
/* TODO maybe this should cause a warning? */
|
/* TODO maybe this should cause a warning? */
|
||||||
printf ("WARNING: clDestroy with non-empty prev\n");
|
eprintf ("WARNING: clDestroy with non-empty prev\n");
|
||||||
cl->prev = NULL;
|
cl->prev = NULL;
|
||||||
}
|
}
|
||||||
while (cl != NULL)
|
while (cl != NULL)
|
||||||
@ -248,14 +248,14 @@ void
|
|||||||
constraintPrint (Constraint co)
|
constraintPrint (Constraint co)
|
||||||
{
|
{
|
||||||
indent ();
|
indent ();
|
||||||
printf ("Constraint ");
|
eprintf ("Constraint ");
|
||||||
if (co == NULL)
|
if (co == NULL)
|
||||||
{
|
{
|
||||||
printf ("[empty]\n");
|
eprintf ("[empty]\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
termPrint (co->term);
|
termPrint (co->term);
|
||||||
printf (" :\n");
|
eprintf (" :\n");
|
||||||
knowledgePrint (co->know);
|
knowledgePrint (co->know);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ constraintlistPrint (Constraintlist cl)
|
|||||||
if (cl == NULL)
|
if (cl == NULL)
|
||||||
{
|
{
|
||||||
indent ();
|
indent ();
|
||||||
printf ("[empty constraintlist]\n");
|
eprintf ("[empty constraintlist]\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (cl != NULL)
|
while (cl != NULL)
|
||||||
|
491
src/depend.c
Normal file
491
src/depend.c
Normal file
@ -0,0 +1,491 @@
|
|||||||
|
/**
|
||||||
|
* @file depend.c
|
||||||
|
* \brief interface for graph code from the viewpoint of events.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "depend.h"
|
||||||
|
#include "term.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "binding.h"
|
||||||
|
#include "warshall.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic structures
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
//! Event dependency structure
|
||||||
|
struct depeventgraph
|
||||||
|
{
|
||||||
|
//! Flag denoting what it was made for (newrun|newbinding)
|
||||||
|
int fornewrun;
|
||||||
|
//! Number of runs;
|
||||||
|
int runs;
|
||||||
|
//! System where it derives from
|
||||||
|
System sys;
|
||||||
|
//! Number of nodes
|
||||||
|
int n;
|
||||||
|
//! Rowsize
|
||||||
|
int rowsize;
|
||||||
|
//! Graph structure
|
||||||
|
unsigned int *G;
|
||||||
|
//! Zombie dummy push
|
||||||
|
int zombie;
|
||||||
|
//! Previous graph
|
||||||
|
struct depeventgraph *prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Pointer shorthard
|
||||||
|
typedef struct depeventgraph *Depeventgraph;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Globals
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
Depeventgraph currentdepgraph;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default code
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! Default init
|
||||||
|
void
|
||||||
|
dependInit (const System sys)
|
||||||
|
{
|
||||||
|
currentdepgraph = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Pring
|
||||||
|
void
|
||||||
|
dependPrint ()
|
||||||
|
{
|
||||||
|
Depeventgraph dg;
|
||||||
|
|
||||||
|
eprintf ("Printing DependEvent stack, top first.\n\n");
|
||||||
|
for (dg = currentdepgraph; dg != NULL; dg = dg->prev)
|
||||||
|
{
|
||||||
|
eprintf ("%i nodes, %i rowsize, %i zombies, %i runs: created for new ",
|
||||||
|
dg->n, dg->rowsize, dg->zombie, dg->runs);
|
||||||
|
if (dg->fornewrun)
|
||||||
|
{
|
||||||
|
eprintf ("run");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eprintf ("binding");
|
||||||
|
}
|
||||||
|
eprintf ("\n");
|
||||||
|
}
|
||||||
|
eprintf ("\n");
|
||||||
|
#ifdef DEBUG
|
||||||
|
{
|
||||||
|
int n1;
|
||||||
|
int r1;
|
||||||
|
int o1;
|
||||||
|
|
||||||
|
r1 = 0;
|
||||||
|
o1 = 0;
|
||||||
|
eprintf ("Printing dependency graph.\n");
|
||||||
|
for (n1 = 0; n1 < nodeCount (); n1++)
|
||||||
|
{
|
||||||
|
int n2;
|
||||||
|
int r2;
|
||||||
|
int o2;
|
||||||
|
|
||||||
|
if ((n1 - o1) >= currentdepgraph->sys->runs[r1].rolelength)
|
||||||
|
{
|
||||||
|
o1 += currentdepgraph->sys->runs[r1].rolelength;
|
||||||
|
r1++;
|
||||||
|
eprintf ("\n");
|
||||||
|
}
|
||||||
|
r2 = 0;
|
||||||
|
o2 = 0;
|
||||||
|
eprintf ("%5i : ", n1);
|
||||||
|
for (n2 = 0; n2 < nodeCount (); n2++)
|
||||||
|
{
|
||||||
|
if ((n2 - o2) >= currentdepgraph->sys->runs[r2].rolelength)
|
||||||
|
{
|
||||||
|
o2 += currentdepgraph->sys->runs[r2].rolelength;
|
||||||
|
r2++;
|
||||||
|
eprintf (" ");
|
||||||
|
}
|
||||||
|
eprintf ("%i", getNode (n1, n2));
|
||||||
|
}
|
||||||
|
eprintf ("\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
eprintf ("\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Default cleanup
|
||||||
|
void
|
||||||
|
dependDone (const System sys)
|
||||||
|
{
|
||||||
|
if (currentdepgraph != NULL)
|
||||||
|
{
|
||||||
|
globalError++;
|
||||||
|
eprintf ("\n\n");
|
||||||
|
dependPrint ();
|
||||||
|
globalError--;
|
||||||
|
error
|
||||||
|
("depgraph stack (depend.c) not empty at dependDone, bad iteration?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Libs
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! Convert from event to node in a graph (given that sys is set)
|
||||||
|
int
|
||||||
|
eventtonode (const Depeventgraph dgx, const int r, const int e)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
for (i = 0; i < dgx->sys->maxruns; i++)
|
||||||
|
{
|
||||||
|
if (i == r)
|
||||||
|
{
|
||||||
|
// this run
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (dgx->sys->runs[i].rolelength <= e)
|
||||||
|
{
|
||||||
|
error ("Bad offset for eventtonode");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return (n + e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// not this run, add offset
|
||||||
|
n += dgx->sys->runs[i].rolelength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
error ("Bad offset (run number too high?) for eventtonode");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Return the number of nodes in a graph
|
||||||
|
int
|
||||||
|
countnodes (const Depeventgraph dgx)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int nodes;
|
||||||
|
|
||||||
|
nodes = 0;
|
||||||
|
for (i = 0; i < dgx->sys->maxruns; i++)
|
||||||
|
{
|
||||||
|
nodes += dgx->sys->runs[i].rolelength;
|
||||||
|
}
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Graph size given the number of nodes
|
||||||
|
unsigned int
|
||||||
|
getGraphSize (const Depeventgraph dgx)
|
||||||
|
{
|
||||||
|
return (dgx->n * dgx->rowsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Create graph from sys
|
||||||
|
Depeventgraph
|
||||||
|
dependCreate (const System sys)
|
||||||
|
{
|
||||||
|
Depeventgraph dgnew;
|
||||||
|
|
||||||
|
dgnew = (Depeventgraph) MALLOC (sizeof (struct depeventgraph));
|
||||||
|
dgnew->sys = sys;
|
||||||
|
dgnew->fornewrun = true;
|
||||||
|
dgnew->runs = sys->maxruns;
|
||||||
|
dgnew->zombie = 0;
|
||||||
|
dgnew->prev = NULL;
|
||||||
|
dgnew->n = countnodes (dgnew); // count nodes works on ->sys
|
||||||
|
dgnew->rowsize = WORDSIZE (dgnew->n);
|
||||||
|
dgnew->G = (unsigned int *) CALLOC (1, getGraphSize (dgnew) * sizeof (unsigned int)); // works on ->n and ->rowsize
|
||||||
|
|
||||||
|
return dgnew;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Copy graph from current one
|
||||||
|
Depeventgraph
|
||||||
|
dependCopy (const Depeventgraph dgold)
|
||||||
|
{
|
||||||
|
Depeventgraph dgnew;
|
||||||
|
|
||||||
|
// Copy old to new
|
||||||
|
dgnew = (Depeventgraph) MALLOC (sizeof (struct depeventgraph));
|
||||||
|
memcpy ((void *) dgnew, (void *) dgold,
|
||||||
|
(size_t) sizeof (struct depeventgraph));
|
||||||
|
|
||||||
|
// New copy
|
||||||
|
dgnew->fornewrun = false;
|
||||||
|
dgnew->zombie = 0;
|
||||||
|
|
||||||
|
// copy inner graph
|
||||||
|
dgnew->G =
|
||||||
|
(unsigned int *) MALLOC (getGraphSize (dgold) * sizeof (unsigned int));
|
||||||
|
memcpy ((void *) dgnew->G, (void *) dgold->G,
|
||||||
|
getGraphSize (dgold) * sizeof (unsigned int));
|
||||||
|
|
||||||
|
return dgnew;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Destroy graph
|
||||||
|
void
|
||||||
|
dependDestroy (const Depeventgraph dgold)
|
||||||
|
{
|
||||||
|
FREE (dgold->G);
|
||||||
|
FREE (dgold);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! push graph to stack (generic)
|
||||||
|
void
|
||||||
|
dependPushGeneric (Depeventgraph dgnew)
|
||||||
|
{
|
||||||
|
dgnew->prev = currentdepgraph;
|
||||||
|
currentdepgraph = dgnew;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! restore graph from stack (generic)
|
||||||
|
void
|
||||||
|
dependPopGeneric (void)
|
||||||
|
{
|
||||||
|
Depeventgraph dgprev;
|
||||||
|
|
||||||
|
dgprev = currentdepgraph->prev;
|
||||||
|
dependDestroy (currentdepgraph);
|
||||||
|
currentdepgraph = dgprev;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Construct graph dependencies from sys
|
||||||
|
/**
|
||||||
|
* uses currentdepgraph->sys
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dependFromSys (void)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
List bl;
|
||||||
|
|
||||||
|
// There are two types of orderings.
|
||||||
|
// 1. Role orderings (within runs)
|
||||||
|
for (r = 0; r < currentdepgraph->sys->maxruns; r++)
|
||||||
|
{
|
||||||
|
int e;
|
||||||
|
|
||||||
|
for (e = 1; e < currentdepgraph->sys->runs[r].rolelength; e++)
|
||||||
|
{
|
||||||
|
setDependEvent (r, e - 1, r, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Binding orderings
|
||||||
|
// We implicitly assume these cause no cycles (by construction this is
|
||||||
|
// correct)
|
||||||
|
for (bl = currentdepgraph->sys->bindings; bl != NULL; bl = bl->next)
|
||||||
|
{
|
||||||
|
Binding b;
|
||||||
|
|
||||||
|
b = (Binding) bl->data;
|
||||||
|
if (valid_binding (b))
|
||||||
|
{
|
||||||
|
int r1, e1, r2, e2;
|
||||||
|
|
||||||
|
r1 = b->run_from;
|
||||||
|
e1 = b->ev_from;
|
||||||
|
r2 = b->run_to;
|
||||||
|
e2 = b->ev_to;
|
||||||
|
if (!((r1 == r2) && (e1 == e2)))
|
||||||
|
{
|
||||||
|
// Not a self-binding
|
||||||
|
setDependEvent (r1, e1, r2, e2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Detect whether the graph has a cycle. If so, a node can get to itself (through the cycle)
|
||||||
|
int
|
||||||
|
hasCycle ()
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (n = 0; n < currentdepgraph->n; n++)
|
||||||
|
{
|
||||||
|
if (getNode (n, n))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Public Code
|
||||||
|
* ---------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! get node
|
||||||
|
int
|
||||||
|
getNode (const int n1, const int n2)
|
||||||
|
{
|
||||||
|
return BIT (currentdepgraph->G + currentdepgraph->rowsize * n1, n2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! set node
|
||||||
|
void
|
||||||
|
setNode (const int n1, const int n2)
|
||||||
|
{
|
||||||
|
SETBIT (currentdepgraph->G + currentdepgraph->rowsize * n1, n2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Count nodes
|
||||||
|
int
|
||||||
|
nodeCount (void)
|
||||||
|
{
|
||||||
|
return countnodes (currentdepgraph);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simple setting
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
setDependEvent (const int r1, const int e1, const int r2, const int e2)
|
||||||
|
{
|
||||||
|
int n1, n2;
|
||||||
|
|
||||||
|
n1 = eventtonode (currentdepgraph, r1, e1);
|
||||||
|
n2 = eventtonode (currentdepgraph, r2, e2);
|
||||||
|
setNode (n1, n2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simple testing
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
isDependEvent (const int r1, const int e1, const int r2, const int e2)
|
||||||
|
{
|
||||||
|
int n1, n2;
|
||||||
|
|
||||||
|
n1 = eventtonode (currentdepgraph, r1, e1);
|
||||||
|
n2 = eventtonode (currentdepgraph, r2, e2);
|
||||||
|
return getNode (n1, n2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! create new graph after adding runs or events (new number of nodes)
|
||||||
|
void
|
||||||
|
dependPushRun (const System sys)
|
||||||
|
{
|
||||||
|
dependPushGeneric (dependCreate (sys));
|
||||||
|
dependFromSys ();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! restore graph to state after previous run add
|
||||||
|
void
|
||||||
|
dependPopRun (void)
|
||||||
|
{
|
||||||
|
if (!currentdepgraph->fornewrun)
|
||||||
|
{
|
||||||
|
globalError++;
|
||||||
|
dependPrint ();
|
||||||
|
globalError--;
|
||||||
|
error ("Trying to pop graph created for new binding.");
|
||||||
|
}
|
||||||
|
dependPopGeneric ();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! create new graph by adding event bindings
|
||||||
|
/*
|
||||||
|
* The push code returns true or false: if false, the operation fails because
|
||||||
|
* it there is now a cycle in the graph, and there is no need to pop the
|
||||||
|
* result.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
dependPushEvent (const int r1, const int e1, const int r2, const int e2)
|
||||||
|
{
|
||||||
|
if (isDependEvent (r2, e2, r1, e1))
|
||||||
|
{
|
||||||
|
// Adding would imply a cycle, so we won't do that.
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (DEBUGL (3))
|
||||||
|
{
|
||||||
|
eprintf ("Cycle detected for binding %i,%i -> %i,%i.\n", r1, e1, r2,
|
||||||
|
e2);
|
||||||
|
}
|
||||||
|
if (DEBUGL (5))
|
||||||
|
{
|
||||||
|
dependPrint ();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No immediate cycle: new graph, return true TODO disabled
|
||||||
|
if ((1 == 0) && ((r1 == r2) && (e1 == e2))
|
||||||
|
|| isDependEvent (r1, e1, r2, e2))
|
||||||
|
{
|
||||||
|
// if n->n or the binding already existed, no changes
|
||||||
|
// no change: add zombie
|
||||||
|
currentdepgraph->zombie += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// change: make new graph copy of the old one
|
||||||
|
dependPushGeneric (dependCopy (currentdepgraph));
|
||||||
|
// add new binding
|
||||||
|
setDependEvent (r1, e1, r2, e2);
|
||||||
|
// recompute closure
|
||||||
|
transitive_closure (currentdepgraph->G, currentdepgraph->n);
|
||||||
|
// check for cycles
|
||||||
|
if (hasCycle ())
|
||||||
|
{
|
||||||
|
//warning ("Cycle slipped undetected by the reverse check.");
|
||||||
|
// Closure introduced cycle, undo it
|
||||||
|
dependPopEvent ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! restore graph to state before previous binding add
|
||||||
|
void
|
||||||
|
dependPopEvent (void)
|
||||||
|
{
|
||||||
|
if (currentdepgraph->fornewrun)
|
||||||
|
{
|
||||||
|
globalError++;
|
||||||
|
dependPrint ();
|
||||||
|
globalError--;
|
||||||
|
error ("Trying to pop graph created for new run.");
|
||||||
|
}
|
||||||
|
if (currentdepgraph->zombie > 0)
|
||||||
|
{
|
||||||
|
// zombie pushed
|
||||||
|
currentdepgraph->zombie -= 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// real graph
|
||||||
|
dependPopGeneric ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Current event to node
|
||||||
|
int
|
||||||
|
eventNode (const int r, const int e)
|
||||||
|
{
|
||||||
|
return eventtonode (currentdepgraph, r, e);
|
||||||
|
}
|
42
src/depend.h
Normal file
42
src/depend.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef DEPEND
|
||||||
|
#define DEPEND
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The code here mainly involves an interface for creating graphs etc., but
|
||||||
|
* most of it is implicit: we just add dependencies/runs and undo them again
|
||||||
|
* later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void dependInit (const System sys);
|
||||||
|
void dependPrint ();
|
||||||
|
void dependDone (const System sys);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The push code returns true or false: if false, the operation fails because
|
||||||
|
* it there is now a cycle in the graph, and there is no need to pop the
|
||||||
|
* result.
|
||||||
|
*/
|
||||||
|
void dependPushRun (const System sys);
|
||||||
|
void dependPopRun ();
|
||||||
|
int dependPushEvent (const int r1, const int e1, const int r2, const int e2);
|
||||||
|
void dependPopEvent ();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test/set
|
||||||
|
*/
|
||||||
|
|
||||||
|
int getNode (const int n1, const int n2);
|
||||||
|
void setNode (const int n1, const int n2);
|
||||||
|
int isDependEvent (const int r1, const int e1, const int r2, const int e2);
|
||||||
|
void setDependEvent (const int r1, const int e1, const int r2, const int e2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Outside helpers
|
||||||
|
*/
|
||||||
|
int hasCycle ();
|
||||||
|
int eventNode (const int r, const int e);
|
||||||
|
int nodeCount (void);
|
||||||
|
|
||||||
|
#endif
|
149
src/dotout.c
149
src/dotout.c
@ -2,10 +2,8 @@
|
|||||||
#include "switches.h"
|
#include "switches.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "arachne.h"
|
#include "arachne.h"
|
||||||
|
#include "depend.h"
|
||||||
extern int *graph;
|
#include <limits.h>
|
||||||
extern int nodes;
|
|
||||||
extern int graph_uordblks;
|
|
||||||
|
|
||||||
extern Protocol INTRUDER; // Pointers, to be set by the Init of arachne.c
|
extern Protocol INTRUDER; // Pointers, to be set by the Init of arachne.c
|
||||||
extern Role I_M; // Same here.
|
extern Role I_M; // Same here.
|
||||||
@ -17,6 +15,70 @@ extern Role I_RRSD;
|
|||||||
#define isBound(rd) (rd->bound)
|
#define isBound(rd) (rd->bound)
|
||||||
#define length step
|
#define length step
|
||||||
|
|
||||||
|
|
||||||
|
//! Determine ranks for all nodes
|
||||||
|
/**
|
||||||
|
* Some crude algorithm I sketched on the blackboard.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
graph_ranks (int *ranks, int nodes)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int todo;
|
||||||
|
int rank;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (hasCycle ())
|
||||||
|
{
|
||||||
|
error ("Graph ranks tried, but a cycle exists!");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < nodes)
|
||||||
|
{
|
||||||
|
ranks[i] = INT_MAX;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
todo = nodes;
|
||||||
|
rank = 0;
|
||||||
|
while (todo > 0)
|
||||||
|
{
|
||||||
|
// There are still unassigned nodes
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
while (n < nodes)
|
||||||
|
{
|
||||||
|
if (ranks[n] == INT_MAX)
|
||||||
|
{
|
||||||
|
// Does this node have incoming stuff from stuff with equal rank or higher?
|
||||||
|
int refn;
|
||||||
|
|
||||||
|
refn = 0;
|
||||||
|
while (refn < nodes)
|
||||||
|
{
|
||||||
|
if (ranks[refn] >= rank && getNode (refn, n))
|
||||||
|
refn = nodes + 1;
|
||||||
|
else
|
||||||
|
refn++;
|
||||||
|
}
|
||||||
|
if (refn == nodes)
|
||||||
|
{
|
||||||
|
ranks[n] = rank;
|
||||||
|
todo--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
rank++;
|
||||||
|
}
|
||||||
|
return rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! Iterate over all events that have an incoming arrow to the current one (forgetting the intruder for a moment)
|
//! Iterate over all events that have an incoming arrow to the current one (forgetting the intruder for a moment)
|
||||||
void
|
void
|
||||||
iterate_incoming_arrows (const System sys, void (*func) (), const int run,
|
iterate_incoming_arrows (const System sys, void (*func) (), const int run,
|
||||||
@ -42,7 +104,7 @@ iterate_incoming_arrows (const System sys, void (*func) (), const int run,
|
|||||||
while (found == 0 && ev2 > 0)
|
while (found == 0 && ev2 > 0)
|
||||||
{
|
{
|
||||||
ev2--;
|
ev2--;
|
||||||
if (graph[graph_nodes (nodes, run2, ev2, run, ev)] != 0)
|
if (isDependEvent (run2, ev2, run, ev))
|
||||||
{
|
{
|
||||||
found = 1;
|
found = 1;
|
||||||
}
|
}
|
||||||
@ -72,12 +134,8 @@ iterate_incoming_arrows (const System sys, void (*func) (), const int run,
|
|||||||
ev3 = 0;
|
ev3 = 0;
|
||||||
while (other_route == 0 && ev3 < sys->runs[run3].length)
|
while (other_route == 0 && ev3 < sys->runs[run3].length)
|
||||||
{
|
{
|
||||||
if (graph
|
if (isDependEvent (run2, ev2, run3, ev3)
|
||||||
[graph_nodes
|
&& isDependEvent (run3, ev3, run, ev))
|
||||||
(nodes, run2, ev2, run3, ev3)] != 0
|
|
||||||
&&
|
|
||||||
graph[graph_nodes
|
|
||||||
(nodes, run3, ev3, run, ev)] != 0)
|
|
||||||
{
|
{
|
||||||
// other route found
|
// other route found
|
||||||
other_route = 1;
|
other_route = 1;
|
||||||
@ -123,7 +181,7 @@ iterate_outgoing_arrows (const System sys, void (*func) (), const int run,
|
|||||||
ev2 = 0;
|
ev2 = 0;
|
||||||
while (found == 0 && ev2 < sys->runs[run2].length)
|
while (found == 0 && ev2 < sys->runs[run2].length)
|
||||||
{
|
{
|
||||||
if (graph[graph_nodes (nodes, run, ev, run2, ev2)] != 0)
|
if (isDependEvent (run, ev, run2, ev2))
|
||||||
{
|
{
|
||||||
found = 1;
|
found = 1;
|
||||||
}
|
}
|
||||||
@ -157,12 +215,8 @@ iterate_outgoing_arrows (const System sys, void (*func) (), const int run,
|
|||||||
ev3 = 0;
|
ev3 = 0;
|
||||||
while (other_route == 0 && ev3 < sys->runs[run3].length)
|
while (other_route == 0 && ev3 < sys->runs[run3].length)
|
||||||
{
|
{
|
||||||
if (graph
|
if (isDependEvent (run, ev, run3, ev3)
|
||||||
[graph_nodes
|
&& isDependEvent (run3, ev3, run2, ev2))
|
||||||
(nodes, run, ev, run3, ev3)] != 0
|
|
||||||
&&
|
|
||||||
graph[graph_nodes
|
|
||||||
(nodes, run3, ev3, run2, ev2)] != 0)
|
|
||||||
{
|
{
|
||||||
// other route found
|
// other route found
|
||||||
other_route = 1;
|
other_route = 1;
|
||||||
@ -196,6 +250,7 @@ dotSemiState (const System sys)
|
|||||||
int *ranks;
|
int *ranks;
|
||||||
int maxrank;
|
int maxrank;
|
||||||
int from_intruder_count;
|
int from_intruder_count;
|
||||||
|
int nodes;
|
||||||
|
|
||||||
void node (const int run, const int index)
|
void node (const int run, const int index)
|
||||||
{
|
{
|
||||||
@ -231,15 +286,10 @@ dotSemiState (const System sys)
|
|||||||
from_intruder_count = 0; // number of terms that can come from the initial knowledge
|
from_intruder_count = 0; // number of terms that can come from the initial knowledge
|
||||||
|
|
||||||
// Needed for the bindings later on: create graph
|
// Needed for the bindings later on: create graph
|
||||||
goal_graph_create (); // create graph
|
|
||||||
if (warshall (graph, nodes) == 0) // determine closure
|
|
||||||
{
|
|
||||||
eprintf
|
|
||||||
("// This graph was not completely closed transitively because it contains a cycle!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
nodes = nodeCount ();
|
||||||
ranks = memAlloc (nodes * sizeof (int));
|
ranks = memAlloc (nodes * sizeof (int));
|
||||||
maxrank = graph_ranks (graph, ranks, nodes); // determine ranks
|
maxrank = graph_ranks (ranks, nodes); // determine ranks
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// For debugging purposes, we also display an ASCII version of some stuff in the comments
|
// For debugging purposes, we also display an ASCII version of some stuff in the comments
|
||||||
@ -272,7 +322,7 @@ dotSemiState (const System sys)
|
|||||||
ev2 = 0;
|
ev2 = 0;
|
||||||
while (ev2 < sys->runs[run2].length)
|
while (ev2 < sys->runs[run2].length)
|
||||||
{
|
{
|
||||||
if (graph[graph_nodes (nodes, run2, ev2, run, ev)] != 0)
|
if (isDependEvent (run2, ev2, run, ev))
|
||||||
{
|
{
|
||||||
if (notfirstev)
|
if (notfirstev)
|
||||||
eprintf (",");
|
eprintf (",");
|
||||||
@ -518,6 +568,43 @@ dotSemiState (const System sys)
|
|||||||
("\tintruder [label=\"Initial intruder knowledge\", color=red];\n");
|
("\tintruder [label=\"Initial intruder knowledge\", color=red];\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For debugging we might add more stuff: full dependencies
|
||||||
|
#ifdef DEBUG
|
||||||
|
{
|
||||||
|
int r1;
|
||||||
|
|
||||||
|
for (r1 = 0; r1 < sys->maxruns; r1++)
|
||||||
|
{
|
||||||
|
if (sys->runs[r1].protocol != INTRUDER)
|
||||||
|
{
|
||||||
|
int e1;
|
||||||
|
|
||||||
|
for (e1 = 0; e1 < sys->runs[r1].step; e1++)
|
||||||
|
{
|
||||||
|
int r2;
|
||||||
|
|
||||||
|
for (r2 = 0; r2 < sys->maxruns; r2++)
|
||||||
|
{
|
||||||
|
if (sys->runs[r2].protocol != INTRUDER)
|
||||||
|
{
|
||||||
|
int e2;
|
||||||
|
|
||||||
|
for (e2 = 0; e2 < sys->runs[r2].step; e2++)
|
||||||
|
{
|
||||||
|
if (isDependEvent (r1, e1, r2, e2))
|
||||||
|
{
|
||||||
|
eprintf ("\tr%ii%i -> r%ii%i [color=grey];\n",
|
||||||
|
r1, e1, r2, e2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Fourth, all ranking info
|
// Fourth, all ranking info
|
||||||
{
|
{
|
||||||
int myrank;
|
int myrank;
|
||||||
@ -555,7 +642,7 @@ dotSemiState (const System sys)
|
|||||||
ev = 0;
|
ev = 0;
|
||||||
while (ev < sys->runs[run].step)
|
while (ev < sys->runs[run].step)
|
||||||
{
|
{
|
||||||
if (myrank == ranks[node_number (run, ev)])
|
if (myrank == ranks[eventNode (run, ev)])
|
||||||
{
|
{
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
eprintf ("\t{ rank = same; ");
|
eprintf ("\t{ rank = same; ");
|
||||||
@ -573,6 +660,14 @@ dotSemiState (const System sys)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
// Debug: print dependencies
|
||||||
|
if (DEBUGL (3))
|
||||||
|
{
|
||||||
|
dependPrint ();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// clean memory
|
// clean memory
|
||||||
memFree (ranks, nodes * sizeof (int)); // ranks
|
memFree (ranks, nodes * sizeof (int)); // ranks
|
||||||
|
|
||||||
|
@ -20,12 +20,12 @@ is_goal_selectable (const Binding b)
|
|||||||
{
|
{
|
||||||
if (b != NULL)
|
if (b != NULL)
|
||||||
{
|
{
|
||||||
if (!b->blocked && !b->done)
|
if ((!b->blocked) && (!b->done))
|
||||||
{
|
{
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Count selectable goals
|
//! Count selectable goals
|
||||||
|
@ -80,9 +80,15 @@ hidelevelCompute (const System sys)
|
|||||||
|
|
||||||
sys->hidden = NULL;
|
sys->hidden = NULL;
|
||||||
tl = sys->globalconstants;
|
tl = sys->globalconstants;
|
||||||
eprintf ("Global constants: ");
|
|
||||||
termlistPrint (tl);
|
#ifdef DEBUG
|
||||||
eprintf ("\n");
|
if (DEBUGL (4))
|
||||||
|
{
|
||||||
|
eprintf ("Global constants: ");
|
||||||
|
termlistPrint (tl);
|
||||||
|
eprintf ("\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
while (tl != NULL)
|
while (tl != NULL)
|
||||||
{
|
{
|
||||||
@ -113,9 +119,12 @@ hidelevelCompute (const System sys)
|
|||||||
sys->hidden = ht;
|
sys->hidden = ht;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
eprintf ("Added possibly interesting term: ");
|
if (DEBUGL (5))
|
||||||
termPrint (tl->term);
|
{
|
||||||
eprintf ("; know %i, prot %i\n", l1, l2);
|
eprintf ("Added possibly interesting term: ");
|
||||||
|
termPrint (tl->term);
|
||||||
|
eprintf ("; know %i, prot %i\n", l1, l2);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
276
src/latex.c
276
src/latex.c
@ -62,20 +62,20 @@ latexInit (const System sys, int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
printf ("%%\n");
|
eprintf ("%%\n");
|
||||||
printf ("%% LaTeX output generated by %s\n", progname);
|
eprintf ("%% LaTeX output generated by %s\n", progname);
|
||||||
printf ("%% Input:\n");
|
eprintf ("%% Input:\n");
|
||||||
|
|
||||||
/* print command line */
|
/* print command line */
|
||||||
printf ("%% $");
|
eprintf ("%% $");
|
||||||
for (i = 0; i < argc; i++)
|
for (i = 0; i < argc; i++)
|
||||||
printf (" %s", argv[i]);
|
eprintf (" %s", argv[i]);
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
|
|
||||||
printf ("%%\n");
|
eprintf ("%%\n");
|
||||||
|
|
||||||
/* comment macro (used for debugging) */
|
/* comment macro (used for debugging) */
|
||||||
printf ("\\newcommand{\\comment}[1]{}\n");
|
eprintf ("\\newcommand{\\comment}[1]{}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Close up any LaTeX output.
|
//! Close up any LaTeX output.
|
||||||
@ -102,7 +102,7 @@ latexTermPrint (Term term, Termlist highlight)
|
|||||||
{
|
{
|
||||||
if (term == NULL)
|
if (term == NULL)
|
||||||
{
|
{
|
||||||
printf ("Empty term");
|
eprintf ("Empty term");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -116,27 +116,27 @@ latexTermPrint (Term term, Termlist highlight)
|
|||||||
if (realTermLeaf (term))
|
if (realTermLeaf (term))
|
||||||
{
|
{
|
||||||
if (inTermlist (highlight, term))
|
if (inTermlist (highlight, term))
|
||||||
printf ("\\mathbf{");
|
eprintf ("\\mathbf{");
|
||||||
symbolPrint (TermSymb (term));
|
symbolPrint (TermSymb (term));
|
||||||
if (realTermVariable (term))
|
if (realTermVariable (term))
|
||||||
printf ("V");
|
eprintf ("V");
|
||||||
if (TermRunid (term) >= 0)
|
if (TermRunid (term) >= 0)
|
||||||
{
|
{
|
||||||
printf ("\\sharp%i", TermRunid (term));
|
eprintf ("\\sharp%i", TermRunid (term));
|
||||||
}
|
}
|
||||||
if (term->subst != NULL)
|
if (term->subst != NULL)
|
||||||
{
|
{
|
||||||
printf ("\\rightarrow");
|
eprintf ("\\rightarrow");
|
||||||
latexTermPrint (term->subst, highlight);
|
latexTermPrint (term->subst, highlight);
|
||||||
}
|
}
|
||||||
if (inTermlist (highlight, term))
|
if (inTermlist (highlight, term))
|
||||||
printf ("}");
|
eprintf ("}");
|
||||||
}
|
}
|
||||||
if (realTermTuple (term))
|
if (realTermTuple (term))
|
||||||
{
|
{
|
||||||
printf ("(");
|
eprintf ("(");
|
||||||
latexTermTuplePrint (term, highlight);
|
latexTermTuplePrint (term, highlight);
|
||||||
printf (")");
|
eprintf (")");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (realTermEncrypt (term))
|
if (realTermEncrypt (term))
|
||||||
@ -146,18 +146,18 @@ latexTermPrint (Term term, Termlist highlight)
|
|||||||
{
|
{
|
||||||
/* function application */
|
/* function application */
|
||||||
latexTermPrint (TermKey (term), highlight);
|
latexTermPrint (TermKey (term), highlight);
|
||||||
printf ("(");
|
eprintf ("(");
|
||||||
latexTermTuplePrint (TermOp (term), highlight);
|
latexTermTuplePrint (TermOp (term), highlight);
|
||||||
printf (")");
|
eprintf (")");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* normal encryption */
|
/* normal encryption */
|
||||||
printf ("\\{");
|
eprintf ("\\{");
|
||||||
latexTermTuplePrint (TermOp (term), highlight);
|
latexTermTuplePrint (TermOp (term), highlight);
|
||||||
printf ("\\}_{");
|
eprintf ("\\}_{");
|
||||||
latexTermPrint (TermKey (term), highlight);
|
latexTermPrint (TermKey (term), highlight);
|
||||||
printf ("}");
|
eprintf ("}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,7 +173,7 @@ latexTermTuplePrint (Term term, Termlist hl)
|
|||||||
{
|
{
|
||||||
if (term == NULL)
|
if (term == NULL)
|
||||||
{
|
{
|
||||||
printf ("Empty term");
|
eprintf ("Empty term");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
term = deVar (term);
|
term = deVar (term);
|
||||||
@ -181,7 +181,7 @@ latexTermTuplePrint (Term term, Termlist hl)
|
|||||||
{
|
{
|
||||||
// To remove any brackets, change this into latexTermTuplePrint.
|
// To remove any brackets, change this into latexTermTuplePrint.
|
||||||
latexTermPrint (TermOp1 (term), hl);
|
latexTermPrint (TermOp1 (term), hl);
|
||||||
printf (",");
|
eprintf (",");
|
||||||
term = deVar (TermOp2 (term));
|
term = deVar (TermOp2 (term));
|
||||||
}
|
}
|
||||||
latexTermPrint (term, hl);
|
latexTermPrint (term, hl);
|
||||||
@ -201,7 +201,7 @@ latexTermlistPrint (Termlist tl, Termlist highlight)
|
|||||||
{
|
{
|
||||||
if (tl == NULL)
|
if (tl == NULL)
|
||||||
{
|
{
|
||||||
printf ("\\emptyset");
|
eprintf ("\\emptyset");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (tl != NULL)
|
while (tl != NULL)
|
||||||
@ -209,7 +209,7 @@ latexTermlistPrint (Termlist tl, Termlist highlight)
|
|||||||
latexTermPrint (tl->term, highlight);
|
latexTermPrint (tl->term, highlight);
|
||||||
tl = tl->next;
|
tl = tl->next;
|
||||||
if (tl != NULL)
|
if (tl != NULL)
|
||||||
printf (", ");
|
eprintf (", ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,11 +233,11 @@ void
|
|||||||
latexMSCStart (Termlist protocolnames)
|
latexMSCStart (Termlist protocolnames)
|
||||||
{
|
{
|
||||||
if (landscape)
|
if (landscape)
|
||||||
printf ("\\begin{landscape}\n");
|
eprintf ("\\begin{landscape}\n");
|
||||||
|
|
||||||
printf ("\\begin{msc}{attack on $");
|
eprintf ("\\begin{msc}{attack on $");
|
||||||
termlistPrint (protocolnames);
|
termlistPrint (protocolnames);
|
||||||
printf ("$}\n");
|
eprintf ("$}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Close drawing MSC
|
//! Close drawing MSC
|
||||||
@ -245,10 +245,10 @@ latexMSCStart (Termlist protocolnames)
|
|||||||
void
|
void
|
||||||
latexMSCEnd ()
|
latexMSCEnd ()
|
||||||
{
|
{
|
||||||
printf ("\\end{msc}\n");
|
eprintf ("\\end{msc}\n");
|
||||||
|
|
||||||
if (landscape)
|
if (landscape)
|
||||||
printf ("\\end{landscape}\n");
|
eprintf ("\\end{landscape}\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,43 +272,43 @@ latexDeclInst (const System sys, int run)
|
|||||||
myRole = sys->runs[run].role->nameterm;
|
myRole = sys->runs[run].role->nameterm;
|
||||||
if (pass == 1)
|
if (pass == 1)
|
||||||
{
|
{
|
||||||
printf ("\\maxlength{\\maxmscinst}{");
|
eprintf ("\\maxlength{\\maxmscinst}{");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf ("\\declinst{run%i}{", run);
|
eprintf ("\\declinst{run%i}{", run);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* display above assumptions */
|
/* display above assumptions */
|
||||||
roles = sys->runs[run].protocol->rolenames;
|
roles = sys->runs[run].protocol->rolenames;
|
||||||
if (pass == 2)
|
if (pass == 2)
|
||||||
{
|
{
|
||||||
printf ("assumes $");
|
eprintf ("assumes $");
|
||||||
first = 1;
|
first = 1;
|
||||||
while (roles != NULL)
|
while (roles != NULL)
|
||||||
{
|
{
|
||||||
if (!isTermEqual (myRole, roles->term))
|
if (!isTermEqual (myRole, roles->term))
|
||||||
{
|
{
|
||||||
if (!first)
|
if (!first)
|
||||||
printf (", ");
|
eprintf (", ");
|
||||||
else
|
else
|
||||||
first = 0;
|
first = 0;
|
||||||
termPrint (agentOfRunRole (sys, run, roles->term));
|
termPrint (agentOfRunRole (sys, run, roles->term));
|
||||||
printf (": ");
|
eprintf (": ");
|
||||||
termPrint (roles->term);
|
termPrint (roles->term);
|
||||||
}
|
}
|
||||||
roles = roles->next;
|
roles = roles->next;
|
||||||
}
|
}
|
||||||
printf ("$}{");
|
eprintf ("$}{");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* display agent and role */
|
/* display agent and role */
|
||||||
printf ("$\\mathbf{");
|
eprintf ("$\\mathbf{");
|
||||||
termPrint (myAgent);
|
termPrint (myAgent);
|
||||||
printf ("}: ");
|
eprintf ("}: ");
|
||||||
termPrint (myRole);
|
termPrint (myRole);
|
||||||
|
|
||||||
printf ("$}\n");
|
eprintf ("$}\n");
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
termDelete (myAgent);
|
termDelete (myAgent);
|
||||||
@ -332,9 +332,9 @@ latexEventSpace (int amount)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("%% number of newlines: %d\n",amount);
|
//eprintf("%% number of newlines: %d\n",amount);
|
||||||
for (i = 0; i < EVENTSPACE * amount; i++)
|
for (i = 0; i < EVENTSPACE * amount; i++)
|
||||||
printf ("\\nextlevel\n");
|
eprintf ("\\nextlevel\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! MSC message print.
|
//! MSC message print.
|
||||||
@ -371,36 +371,36 @@ latexMessagePrint (struct tracebuf *tb, int from, int to)
|
|||||||
if (from == -1 && to != -1)
|
if (from == -1 && to != -1)
|
||||||
{
|
{
|
||||||
/* message from intruder into system */
|
/* message from intruder into system */
|
||||||
printf ("\\mess{$");
|
eprintf ("\\mess{$");
|
||||||
termPrint (readTerm);
|
termPrint (readTerm);
|
||||||
printf ("$}{eve}{run%d}\n", tb->run[to]);
|
eprintf ("$}{eve}{run%d}\n", tb->run[to]);
|
||||||
}
|
}
|
||||||
else if (from != -1 && to == -1)
|
else if (from != -1 && to == -1)
|
||||||
{
|
{
|
||||||
/* message from system to intruder */
|
/* message from system to intruder */
|
||||||
printf ("\\mess{$");
|
eprintf ("\\mess{$");
|
||||||
termPrint (sendTerm);
|
termPrint (sendTerm);
|
||||||
printf ("$}{run%d}{eve}\n", tb->run[from]);
|
eprintf ("$}{run%d}{eve}\n", tb->run[from]);
|
||||||
}
|
}
|
||||||
else if (from != -1 && to != -1)
|
else if (from != -1 && to != -1)
|
||||||
{
|
{
|
||||||
/* message from one agent to another, possibly transformed */
|
/* message from one agent to another, possibly transformed */
|
||||||
|
|
||||||
printf ("\\mess{$");
|
eprintf ("\\mess{$");
|
||||||
|
|
||||||
termPrint (sendTerm);
|
termPrint (sendTerm);
|
||||||
|
|
||||||
if (!isTermEqual (sendTerm, readTerm))
|
if (!isTermEqual (sendTerm, readTerm))
|
||||||
{
|
{
|
||||||
printf ("\\rightarrow");
|
eprintf ("\\rightarrow");
|
||||||
termPrint (readTerm);
|
termPrint (readTerm);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("$}{run%d", tb->run[from]);
|
eprintf ("$}{run%d", tb->run[from]);
|
||||||
printf ("}{run%d}[%d]", tb->run[to],
|
eprintf ("}{run%d}[%d]", tb->run[to],
|
||||||
EVENTSPACE * (tinfo[to].position - tinfo[from].position));
|
EVENTSPACE * (tinfo[to].position - tinfo[from].position));
|
||||||
|
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,34 +438,34 @@ latexMessagePrintHighlight (struct tracebuf *tb, int from, int to,
|
|||||||
if (from == -1 && to != -1)
|
if (from == -1 && to != -1)
|
||||||
{
|
{
|
||||||
/* TODO redundant */
|
/* TODO redundant */
|
||||||
printf ("\\found{$");
|
eprintf ("\\found{$");
|
||||||
latexTermPrint (readTerm, highlight);
|
latexTermPrint (readTerm, highlight);
|
||||||
printf ("$}{}{run%d}\n", tb->run[to]);
|
eprintf ("$}{}{run%d}\n", tb->run[to]);
|
||||||
}
|
}
|
||||||
else if (from != -1 && to == -1)
|
else if (from != -1 && to == -1)
|
||||||
{
|
{
|
||||||
printf ("\\mess{$");
|
eprintf ("\\mess{$");
|
||||||
latexTermPrint (sendTerm, highlight);
|
latexTermPrint (sendTerm, highlight);
|
||||||
printf ("$}{run%d}{eve}\n", tb->run[from]);
|
eprintf ("$}{run%d}{eve}\n", tb->run[from]);
|
||||||
}
|
}
|
||||||
else if (from != -1 && to != -1)
|
else if (from != -1 && to != -1)
|
||||||
{
|
{
|
||||||
|
|
||||||
printf ("\\mess{$");
|
eprintf ("\\mess{$");
|
||||||
|
|
||||||
latexTermPrint (sendTerm, highlight);
|
latexTermPrint (sendTerm, highlight);
|
||||||
|
|
||||||
if (!isTermEqual (sendTerm, readTerm))
|
if (!isTermEqual (sendTerm, readTerm))
|
||||||
{
|
{
|
||||||
printf ("\\rightarrow");
|
eprintf ("\\rightarrow");
|
||||||
latexTermPrint (readTerm, highlight);
|
latexTermPrint (readTerm, highlight);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("$}{run%d", tb->run[from]);
|
eprintf ("$}{run%d", tb->run[from]);
|
||||||
printf ("}{run%d}[%d]", tb->run[to],
|
eprintf ("}{run%d}[%d]", tb->run[to],
|
||||||
EVENTSPACE * (tinfo[to].position - tinfo[from].position));
|
EVENTSPACE * (tinfo[to].position - tinfo[from].position));
|
||||||
|
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,22 +479,22 @@ latexClaim (struct tracebuf *tb, int run, Termlist tl)
|
|||||||
{
|
{
|
||||||
if (pass == 1)
|
if (pass == 1)
|
||||||
{
|
{
|
||||||
printf ("\\maxlength{\\maxmsccondition}{");
|
eprintf ("\\maxlength{\\maxmsccondition}{");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf ("\\condition{");
|
eprintf ("\\condition{");
|
||||||
}
|
}
|
||||||
printf ("$\\neg secret ");
|
eprintf ("$\\neg secret ");
|
||||||
termlistPrint (tl);
|
termlistPrint (tl);
|
||||||
printf ("$}");
|
eprintf ("$}");
|
||||||
if (pass == 1)
|
if (pass == 1)
|
||||||
{
|
{
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf ("{run%d}\n", run);
|
eprintf ("{run%d}\n", run);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -547,7 +547,7 @@ latexCorrespondingSend (struct tracebuf *tb, int rd)
|
|||||||
{
|
{
|
||||||
/* bingo! success on all matches */
|
/* bingo! success on all matches */
|
||||||
|
|
||||||
//printf("Found perfect match: %d\n", s);
|
//eprintf("Found perfect match: %d\n", s);
|
||||||
bestSendEvent = sendEvent;
|
bestSendEvent = sendEvent;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -604,7 +604,7 @@ latexCorrespondingSend (struct tracebuf *tb, int rd)
|
|||||||
|
|
||||||
if (bestSendEvent == -1)
|
if (bestSendEvent == -1)
|
||||||
{
|
{
|
||||||
printf ("%% Could not find a matching SEND\n");
|
eprintf ("%% Could not find a matching SEND\n");
|
||||||
}
|
}
|
||||||
return bestSendEvent;
|
return bestSendEvent;
|
||||||
}
|
}
|
||||||
@ -628,9 +628,9 @@ latexCorrespondingSend2 (struct tracebuf *tb, int readEvent)
|
|||||||
if (!inKnowledge (tb->know[u], tb->event[readEvent]->message))
|
if (!inKnowledge (tb->know[u], tb->event[readEvent]->message))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
printf("%% term[");
|
eprintf("%% term[");
|
||||||
printf("]#%d is introduced at traceEvent[%d] ",readEvent,u);
|
eprintf("]#%d is introduced at traceEvent[%d] ",readEvent,u);
|
||||||
printf("\n");
|
eprintf("\n");
|
||||||
*/
|
*/
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
@ -650,7 +650,7 @@ knowledgePrintLatex (Knowledge know)
|
|||||||
|
|
||||||
if (know == NULL)
|
if (know == NULL)
|
||||||
{
|
{
|
||||||
printf ("\\emptyset");
|
eprintf ("\\emptyset");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -681,7 +681,7 @@ attackDisplayLatex (const System sys)
|
|||||||
tb = sys->attack;
|
tb = sys->attack;
|
||||||
if (tb == NULL)
|
if (tb == NULL)
|
||||||
{
|
{
|
||||||
printf ("Attack pointer empty: nothing to display.\n");
|
eprintf ("Attack pointer empty: nothing to display.\n");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
/* set variables */
|
/* set variables */
|
||||||
@ -692,49 +692,49 @@ attackDisplayLatex (const System sys)
|
|||||||
tracebufRebuildKnow (tb);
|
tracebufRebuildKnow (tb);
|
||||||
|
|
||||||
/* Make a comment in which the trace is displayed, for debugging etc. */
|
/* Make a comment in which the trace is displayed, for debugging etc. */
|
||||||
printf ("\n\\comment{ TRACE\n\n");
|
eprintf ("\n\\comment{ TRACE\n\n");
|
||||||
printf ("Length: %i\n", tb->length);
|
eprintf ("Length: %i\n", tb->length);
|
||||||
printf ("Reallength: %i\n", tb->reallength);
|
eprintf ("Reallength: %i\n", tb->reallength);
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i <= tb->length)
|
while (i <= tb->length)
|
||||||
{
|
{
|
||||||
printf ("Knowledge %i:\n", i);
|
eprintf ("Knowledge %i:\n", i);
|
||||||
knowledgePrint (tb->know[i]);
|
knowledgePrint (tb->know[i]);
|
||||||
printf (" [Inverses]: ");
|
eprintf (" [Inverses]: ");
|
||||||
knowledgeInversesPrint (tb->know[i]);
|
knowledgeInversesPrint (tb->know[i]);
|
||||||
printf ("\n\n");
|
eprintf ("\n\n");
|
||||||
if (i < tb->length)
|
if (i < tb->length)
|
||||||
{
|
{
|
||||||
printf ("Event %i\t[", i);
|
eprintf ("Event %i\t[", i);
|
||||||
switch (tb->status[i])
|
switch (tb->status[i])
|
||||||
{
|
{
|
||||||
case S_UNK:
|
case S_UNK:
|
||||||
printf ("?");
|
eprintf ("?");
|
||||||
break;
|
break;
|
||||||
case S_RED:
|
case S_RED:
|
||||||
printf ("redundant");
|
eprintf ("redundant");
|
||||||
break;
|
break;
|
||||||
case S_TOD:
|
case S_TOD:
|
||||||
printf ("to do");
|
eprintf ("to do");
|
||||||
break;
|
break;
|
||||||
case S_OKE:
|
case S_OKE:
|
||||||
printf ("okay");
|
eprintf ("okay");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf ("illegal status code");
|
eprintf ("illegal status code");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf ("]\t");
|
eprintf ("]\t");
|
||||||
termPrint (tb->event[i]->message);
|
termPrint (tb->event[i]->message);
|
||||||
printf ("\t#%i", tb->run[i]);
|
eprintf ("\t#%i", tb->run[i]);
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
roledefPrint (tb->event[i]);
|
roledefPrint (tb->event[i]);
|
||||||
printf ("\n\n");
|
eprintf ("\n\n");
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
printf ("}\n\n");
|
eprintf ("}\n\n");
|
||||||
|
|
||||||
tinfo =
|
tinfo =
|
||||||
(struct traceinfo *) memAlloc ((tb->length + 1) *
|
(struct traceinfo *) memAlloc ((tb->length + 1) *
|
||||||
@ -786,7 +786,7 @@ attackDisplayLatex (const System sys)
|
|||||||
if (tb->event[i]->type == READ && !tb->event[i]->internal)
|
if (tb->event[i]->type == READ && !tb->event[i]->internal)
|
||||||
{
|
{
|
||||||
bestSend = latexCorrespondingSend2 (tb, i);
|
bestSend = latexCorrespondingSend2 (tb, i);
|
||||||
printf ("%% match: %d <-> %d\n", i, bestSend);
|
eprintf ("%% match: %d <-> %d\n", i, bestSend);
|
||||||
if (bestSend == -1)
|
if (bestSend == -1)
|
||||||
continue; // TODO major ugliness
|
continue; // TODO major ugliness
|
||||||
|
|
||||||
@ -801,9 +801,9 @@ attackDisplayLatex (const System sys)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf ("\\comment{ claimDetails :\n");
|
eprintf ("\\comment{ claimDetails :\n");
|
||||||
termlistPrint (claimDetails);
|
termlistPrint (claimDetails);
|
||||||
printf ("\n}\n");
|
eprintf ("\n}\n");
|
||||||
|
|
||||||
// landscape = (width > 4); // not for the time being
|
// landscape = (width > 4); // not for the time being
|
||||||
|
|
||||||
@ -844,16 +844,16 @@ attackDisplayLatex (const System sys)
|
|||||||
if (runPosition[currRun] <= tinfo[tb->link[i]].position
|
if (runPosition[currRun] <= tinfo[tb->link[i]].position
|
||||||
&& currRun != tb->run[tb->link[i]])
|
&& currRun != tb->run[tb->link[i]])
|
||||||
{
|
{
|
||||||
printf ("\\comment{\n");
|
eprintf ("\\comment{\n");
|
||||||
termPrint (tb->event[i]->message);
|
termPrint (tb->event[i]->message);
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
termPrint (tb->event[tb->link[i]]->message);
|
termPrint (tb->event[tb->link[i]]->message);
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
printf ("%% termDistance: %f\n",
|
eprintf ("%% termDistance: %f\n",
|
||||||
termDistance (tb->event[i]->message,
|
termDistance (tb->event[i]->message,
|
||||||
tb->event[tb->link[i]]->
|
tb->event[tb->link[i]]->
|
||||||
message));
|
message));
|
||||||
printf ("}\n");
|
eprintf ("}\n");
|
||||||
tinfo[i].position = tinfo[tb->link[i]].position;
|
tinfo[i].position = tinfo[tb->link[i]].position;
|
||||||
eventSize = 0;
|
eventSize = 0;
|
||||||
}
|
}
|
||||||
@ -879,7 +879,7 @@ attackDisplayLatex (const System sys)
|
|||||||
}
|
}
|
||||||
if (!(tb->event[i]->type == READ && tb->event[i]->internal))
|
if (!(tb->event[i]->type == READ && tb->event[i]->internal))
|
||||||
runPosition[currRun] = tinfo[i].position + eventSize;
|
runPosition[currRun] = tinfo[i].position + eventSize;
|
||||||
/* printf("%% Event %d at %d\n", i, position); */
|
/* eprintf("%% Event %d at %d\n", i, position); */
|
||||||
position += eventSize;
|
position += eventSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -896,12 +896,12 @@ attackDisplayLatex (const System sys)
|
|||||||
|
|
||||||
for (pass = 1; pass <= 2; pass++)
|
for (pass = 1; pass <= 2; pass++)
|
||||||
{
|
{
|
||||||
printf ("%% Pass %i\n\n", pass);
|
eprintf ("%% Pass %i\n\n", pass);
|
||||||
|
|
||||||
if (pass == 1)
|
if (pass == 1)
|
||||||
{
|
{
|
||||||
printf ("\\maxlength{\\maxmscaction}{knows}\n");
|
eprintf ("\\maxlength{\\maxmscaction}{knows}\n");
|
||||||
printf ("\\maxlength{\\maxmscaction}{creates}\n");
|
eprintf ("\\maxlength{\\maxmscaction}{creates}\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -909,18 +909,18 @@ attackDisplayLatex (const System sys)
|
|||||||
Term pname;
|
Term pname;
|
||||||
|
|
||||||
/* slightly stretch measurements */
|
/* slightly stretch measurements */
|
||||||
printf ("\\addtolength{\\maxmscall}{2\\mscspacer}\n");
|
eprintf ("\\addtolength{\\maxmscall}{2\\mscspacer}\n");
|
||||||
printf ("\\addtolength{\\maxmscaction}{\\mscspacer}\n");
|
eprintf ("\\addtolength{\\maxmscaction}{\\mscspacer}\n");
|
||||||
printf ("\\addtolength{\\maxmscinst}{\\mscspacer}\n");
|
eprintf ("\\addtolength{\\maxmscinst}{\\mscspacer}\n");
|
||||||
printf ("\\addtolength{\\maxmsccondition}{\\mscspacer}\n");
|
eprintf ("\\addtolength{\\maxmsccondition}{\\mscspacer}\n");
|
||||||
|
|
||||||
/* put out computed widths */
|
/* put out computed widths */
|
||||||
|
|
||||||
printf ("\\setlength{\\envinstdist}{0.7\\maxmscall}\n");
|
eprintf ("\\setlength{\\envinstdist}{0.7\\maxmscall}\n");
|
||||||
printf ("\\setlength{\\instdist}{\\maxmscall}\n");
|
eprintf ("\\setlength{\\instdist}{\\maxmscall}\n");
|
||||||
printf ("\\setlength{\\actionwidth}{\\maxmscaction}\n");
|
eprintf ("\\setlength{\\actionwidth}{\\maxmscaction}\n");
|
||||||
printf ("\\setlength{\\instwidth}{\\maxmscinst}\n");
|
eprintf ("\\setlength{\\instwidth}{\\maxmscinst}\n");
|
||||||
printf ("\\setlength{\\conditionoverlap}{0.5\\maxmsccondition}\n");
|
eprintf ("\\setlength{\\conditionoverlap}{0.5\\maxmsccondition}\n");
|
||||||
|
|
||||||
/* create MSC title, involving protocol names and such. */
|
/* create MSC title, involving protocol names and such. */
|
||||||
|
|
||||||
@ -949,10 +949,10 @@ attackDisplayLatex (const System sys)
|
|||||||
}
|
}
|
||||||
/* Add the intruder instance */
|
/* Add the intruder instance */
|
||||||
if (pass == 2)
|
if (pass == 2)
|
||||||
printf ("\\declinst{eve}{}{");
|
eprintf ("\\declinst{eve}{}{");
|
||||||
else
|
else
|
||||||
printf ("\\maxlength{\\maxmscinst}{");
|
eprintf ("\\maxlength{\\maxmscinst}{");
|
||||||
printf ("{\\bf Eve}: Intruder}\n\n");
|
eprintf ("{\\bf Eve}: Intruder}\n\n");
|
||||||
|
|
||||||
/* Print the local constants for each instance */
|
/* Print the local constants for each instance */
|
||||||
|
|
||||||
@ -971,14 +971,14 @@ attackDisplayLatex (const System sys)
|
|||||||
if (first)
|
if (first)
|
||||||
{
|
{
|
||||||
if (pass == 1)
|
if (pass == 1)
|
||||||
printf ("\\maxlength{\\maxmscaction}{$");
|
eprintf ("\\maxlength{\\maxmscaction}{$");
|
||||||
else
|
else
|
||||||
printf ("\\ActionBox{creates \\\\\n$");
|
eprintf ("\\ActionBox{creates \\\\\n$");
|
||||||
first = 0;
|
first = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf (", ");
|
eprintf (", ");
|
||||||
}
|
}
|
||||||
termPrint (tl->term);
|
termPrint (tl->term);
|
||||||
}
|
}
|
||||||
@ -987,9 +987,9 @@ attackDisplayLatex (const System sys)
|
|||||||
if (!first)
|
if (!first)
|
||||||
{
|
{
|
||||||
if (pass == 1)
|
if (pass == 1)
|
||||||
printf ("$}\n");
|
eprintf ("$}\n");
|
||||||
else
|
else
|
||||||
printf ("$}{run%i}\n", i);
|
eprintf ("$}{run%i}\n", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -998,13 +998,13 @@ attackDisplayLatex (const System sys)
|
|||||||
|
|
||||||
if (pass == 2)
|
if (pass == 2)
|
||||||
{
|
{
|
||||||
printf ("\\ActionBox{");
|
eprintf ("\\ActionBox{");
|
||||||
printf ("knows \\\\\n$");
|
eprintf ("knows \\\\\n$");
|
||||||
knowledgePrintLatex (tb->know[0]);
|
knowledgePrintLatex (tb->know[0]);
|
||||||
printf ("$}");
|
eprintf ("$}");
|
||||||
printf ("{eve}\n");
|
eprintf ("{eve}\n");
|
||||||
printf ("\\nextlevel[3]\n");
|
eprintf ("\\nextlevel[3]\n");
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* print the events in the attack */
|
/* print the events in the attack */
|
||||||
@ -1059,25 +1059,25 @@ attackDisplayLatex (const System sys)
|
|||||||
|
|
||||||
if (pass == 1)
|
if (pass == 1)
|
||||||
{
|
{
|
||||||
printf ("\\maxlength{\\maxmscaction}{");
|
eprintf ("\\maxlength{\\maxmscaction}{");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf ("\\nextlevel[1]\n");
|
eprintf ("\\nextlevel[1]\n");
|
||||||
printf ("\\ActionBox{learns \\\\\n");
|
eprintf ("\\ActionBox{learns \\\\\n");
|
||||||
}
|
}
|
||||||
printf ("$");
|
eprintf ("$");
|
||||||
cKnowledge++;
|
cKnowledge++;
|
||||||
latexTermlistPrint (newtl, highlights);
|
latexTermlistPrint (newtl, highlights);
|
||||||
printf ("$}");
|
eprintf ("$}");
|
||||||
if (pass == 1)
|
if (pass == 1)
|
||||||
{
|
{
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf ("{eve}\n");
|
eprintf ("{eve}\n");
|
||||||
printf ("\\nextlevel[2]\n");
|
eprintf ("\\nextlevel[2]\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +267,6 @@ main (int argc, char **argv)
|
|||||||
if (switches.engine == ARACHNE_ENGINE)
|
if (switches.engine == ARACHNE_ENGINE)
|
||||||
{
|
{
|
||||||
arachneDone ();
|
arachneDone ();
|
||||||
bindingDone ();
|
|
||||||
}
|
}
|
||||||
knowledgeDestroy (sys->know);
|
knowledgeDestroy (sys->know);
|
||||||
systemDone (sys);
|
systemDone (sys);
|
||||||
|
12
src/mgu.c
12
src/mgu.c
@ -40,24 +40,24 @@ showSubst (Term t)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
indent ();
|
indent ();
|
||||||
printf ("Substituting ");
|
eprintf ("Substituting ");
|
||||||
termPrint (t);
|
termPrint (t);
|
||||||
printf (", typed ");
|
eprintf (", typed ");
|
||||||
termlistPrint (t->stype);
|
termlistPrint (t->stype);
|
||||||
if (realTermLeaf (t->subst))
|
if (realTermLeaf (t->subst))
|
||||||
{
|
{
|
||||||
printf ("->");
|
eprintf ("->");
|
||||||
termlistPrint (t->subst->stype);
|
termlistPrint (t->subst->stype);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf (", composite term");
|
eprintf (", composite term");
|
||||||
}
|
}
|
||||||
if (t->type != VARIABLE)
|
if (t->type != VARIABLE)
|
||||||
{
|
{
|
||||||
printf (" (bound roleconstant)");
|
eprintf (" (bound roleconstant)");
|
||||||
}
|
}
|
||||||
printf ("\n");
|
eprintf ("\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
23
src/system.c
23
src/system.c
@ -18,6 +18,7 @@
|
|||||||
#include "mgu.h"
|
#include "mgu.h"
|
||||||
#include "switches.h"
|
#include "switches.h"
|
||||||
#include "binding.h"
|
#include "binding.h"
|
||||||
|
#include "depend.h"
|
||||||
#include "specialterm.h"
|
#include "specialterm.h"
|
||||||
|
|
||||||
//! Global flag that signals LaTeX output.
|
//! Global flag that signals LaTeX output.
|
||||||
@ -195,6 +196,13 @@ systemDone (const System sys)
|
|||||||
roleInstanceDestroy (sys);
|
roleInstanceDestroy (sys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* undo bindings (for arachne) */
|
||||||
|
|
||||||
|
if (switches.engine == ARACHNE_ENGINE)
|
||||||
|
{
|
||||||
|
bindingDone ();
|
||||||
|
}
|
||||||
|
|
||||||
/* clear substructures */
|
/* clear substructures */
|
||||||
termlistDestroy (sys->secrets);
|
termlistDestroy (sys->secrets);
|
||||||
|
|
||||||
@ -812,6 +820,12 @@ roleInstanceArachne (const System sys, const Protocol protocol,
|
|||||||
|
|
||||||
/* erase any substitutions in the role definition, as they are now copied */
|
/* erase any substitutions in the role definition, as they are now copied */
|
||||||
termlistSubstReset (role->variables);
|
termlistSubstReset (role->variables);
|
||||||
|
|
||||||
|
/* length */
|
||||||
|
runs[rid].rolelength = roledef_length (runs[rid].start);
|
||||||
|
|
||||||
|
/* new graph to create */
|
||||||
|
dependPushRun (sys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -949,6 +963,9 @@ roleInstanceModelchecker (const System sys, const Protocol protocol,
|
|||||||
/* Determine first read with variables besides agents */
|
/* Determine first read with variables besides agents */
|
||||||
runs[rid].firstNonAgentRead = firstNonAgentRead (sys, rid); // symmetry reduction type II
|
runs[rid].firstNonAgentRead = firstNonAgentRead (sys, rid); // symmetry reduction type II
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* length */
|
||||||
|
runs[rid].rolelength = roledef_length (runs[rid].start);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Instantiate a role by making a new run
|
//! Instantiate a role by making a new run
|
||||||
@ -989,6 +1006,12 @@ roleInstanceDestroy (const System sys)
|
|||||||
runid = sys->maxruns - 1;
|
runid = sys->maxruns - 1;
|
||||||
myrun = sys->runs[runid];
|
myrun = sys->runs[runid];
|
||||||
|
|
||||||
|
// Reset graph
|
||||||
|
if (switches.engine == ARACHNE_ENGINE)
|
||||||
|
{
|
||||||
|
dependPopRun ();
|
||||||
|
}
|
||||||
|
|
||||||
// Destroy roledef
|
// Destroy roledef
|
||||||
roledefDestroy (myrun.start);
|
roledefDestroy (myrun.start);
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ struct run
|
|||||||
Role role; //!< Role of this run.
|
Role role; //!< Role of this run.
|
||||||
Termlist agents; //!< Agents involved in this run.
|
Termlist agents; //!< Agents involved in this run.
|
||||||
int step; //!< Current execution point in the run (integer)
|
int step; //!< Current execution point in the run (integer)
|
||||||
|
int rolelength; //!< Length of role
|
||||||
Roledef index; //!< Current execution point in the run (roledef pointer)
|
Roledef index; //!< Current execution point in the run (roledef pointer)
|
||||||
Roledef start; //!< Head of the run definition.
|
Roledef start; //!< Head of the run definition.
|
||||||
Knowledge know; //!< Current knowledge of the run.
|
Knowledge know; //!< Current knowledge of the run.
|
||||||
|
23
src/todo.txt
23
src/todo.txt
@ -1,3 +1,8 @@
|
|||||||
|
- Old version enforced some extra orders:
|
||||||
|
1. M_0 roles were ordered before any other roles.
|
||||||
|
2. Local constants order: if a run has a local variable instantiated by
|
||||||
|
somebody else's variable, that should occur then after the initial sending
|
||||||
|
of that value...
|
||||||
- Test 'sk(x)' in goals, somewhere before assessing a state (dus at the
|
- Test 'sk(x)' in goals, somewhere before assessing a state (dus at the
|
||||||
beginning of iterate), immediately reduce to 'sk(Eve)'. Test with
|
beginning of iterate), immediately reduce to 'sk(Eve)'. Test with
|
||||||
--experimental. To that end, reintroduce a state-reporting switch.
|
--experimental. To that end, reintroduce a state-reporting switch.
|
||||||
@ -7,24 +12,6 @@
|
|||||||
this requires some work at instantiation, because instantiated term
|
this requires some work at instantiation, because instantiated term
|
||||||
couples should be added to the inverses list, and removed at
|
couples should be added to the inverses list, and removed at
|
||||||
descruction.
|
descruction.
|
||||||
- Warshall is taking a third of the time running.
|
|
||||||
- Make 'dirty' flag.
|
|
||||||
- Make a push-graph structure, where old graphs are simply remembered?
|
|
||||||
Does this help at all?
|
|
||||||
- Improve the speed of the thing by finally moving to a bit-thing.
|
|
||||||
Required interface:
|
|
||||||
* Abstract graph (node relations)
|
|
||||||
- make_empty_graph of size n (with ->cycle=0)
|
|
||||||
- destroy graph
|
|
||||||
- get_transitive_relation (g,n1,n2) (enforces closure)
|
|
||||||
- set_transitive_relation (g,n1,n2) (sets dirty flag, checks cycle)
|
|
||||||
- has_cycle (g)
|
|
||||||
* High-level (event dependencies)
|
|
||||||
- make_deps for current sys (make_empty+fill), returning cycle flag
|
|
||||||
- destroy_deps(G)
|
|
||||||
- set_deps (G,r1,s1,r2,s2), returning cycle flag
|
|
||||||
- get_deps (G,r1,s1,r2,s2)
|
|
||||||
- get_cycle_flag (G)
|
|
||||||
- Simple timestamps could be added by prefixing send message before the
|
- Simple timestamps could be added by prefixing send message before the
|
||||||
role, sending any timestamp constants out first to the intruder. These
|
role, sending any timestamp constants out first to the intruder. These
|
||||||
should of course be hidden in the output somehow.
|
should of course be hidden in the output somehow.
|
||||||
|
215
src/warshall.c
215
src/warshall.c
@ -1,168 +1,85 @@
|
|||||||
/**
|
// @file warshall.c
|
||||||
*@file warshall.c
|
/* Based on public-domain code from Berkeley Yacc */
|
||||||
*
|
|
||||||
* Warshall's algorithm for transitive closure computation.
|
|
||||||
*
|
|
||||||
* Currently this is the slow integer-instead-of-bit olde slowe version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include "warshall.h"
|
#include "warshall.h"
|
||||||
#include "debug.h"
|
|
||||||
|
|
||||||
//! fill the graph with some value
|
|
||||||
void
|
void
|
||||||
graph_fill (int *graph, int nodes, int value)
|
transitive_closure (unsigned int *R, int n)
|
||||||
{
|
{
|
||||||
int node;
|
register int rowsize;
|
||||||
|
register unsigned mask;
|
||||||
|
register unsigned *rowj;
|
||||||
|
register unsigned *rp;
|
||||||
|
register unsigned *rend;
|
||||||
|
register unsigned *ccol;
|
||||||
|
register unsigned *relend;
|
||||||
|
register unsigned *cword;
|
||||||
|
register unsigned *rowi;
|
||||||
|
|
||||||
node = 0;
|
rowsize = WORDSIZE (n);
|
||||||
while (node < (nodes * nodes))
|
relend = R + n * rowsize;
|
||||||
|
|
||||||
|
cword = R;
|
||||||
|
mask = 1;
|
||||||
|
rowi = R;
|
||||||
|
while (rowi < relend)
|
||||||
{
|
{
|
||||||
graph[node] = value;
|
ccol = cword;
|
||||||
node++;
|
rowj = R;
|
||||||
|
|
||||||
|
while (rowj < relend)
|
||||||
|
{
|
||||||
|
if (*ccol & mask)
|
||||||
|
{
|
||||||
|
rp = rowi;
|
||||||
|
rend = rowj + rowsize;
|
||||||
|
while (rowj < rend)
|
||||||
|
*rowj++ |= *rp++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rowj += rowsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
ccol += rowsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask <<= 1;
|
||||||
|
if (mask == 0)
|
||||||
|
{
|
||||||
|
mask = 1;
|
||||||
|
cword++;
|
||||||
|
}
|
||||||
|
|
||||||
|
rowi += rowsize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Show a graph
|
|
||||||
void
|
void
|
||||||
graph_display (int *graph, int nodes)
|
reflexive_transitive_closure (unsigned int *R, int n)
|
||||||
{
|
{
|
||||||
int i;
|
register int rowsize;
|
||||||
|
register unsigned mask;
|
||||||
|
register unsigned *rp;
|
||||||
|
register unsigned *relend;
|
||||||
|
|
||||||
int index (const int i, const int j)
|
transitive_closure (R, n);
|
||||||
{
|
|
||||||
return (i * nodes + j);
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
rowsize = WORDSIZE (n);
|
||||||
while (i < nodes)
|
relend = R + n * rowsize;
|
||||||
|
|
||||||
|
mask = 1;
|
||||||
|
rp = R;
|
||||||
|
while (rp < relend)
|
||||||
{
|
{
|
||||||
int j;
|
*rp |= mask;
|
||||||
j = 0;
|
mask <<= 1;
|
||||||
while (j < nodes)
|
if (mask == 0)
|
||||||
{
|
{
|
||||||
eprintf ("%i ", graph[index (i, j)]);
|
mask = 1;
|
||||||
j++;
|
rp++;
|
||||||
}
|
}
|
||||||
eprintf ("\n");
|
|
||||||
i++;
|
rp += rowsize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Apply warshall's algorithm to determine the closure of a graph
|
|
||||||
/**
|
|
||||||
* If j<i and k<j, then k<i.
|
|
||||||
* Could be done more efficiently but that is irrelevant here.
|
|
||||||
*
|
|
||||||
*@param graph A pointer to the integer array of nodes*nodes elements.
|
|
||||||
*@param nodes The number of nodes in the graph.
|
|
||||||
*@Returns 0 if there is a cycle; and the algorithm aborts, 1 if there is no cycle and the result is okay.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
warshall (int *graph, int nodes)
|
|
||||||
{
|
|
||||||
int k;
|
|
||||||
|
|
||||||
int index (const int x, const int y)
|
|
||||||
{
|
|
||||||
return (x * nodes + y);
|
|
||||||
}
|
|
||||||
|
|
||||||
k = 0;
|
|
||||||
while (k < nodes)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while (i < nodes)
|
|
||||||
{
|
|
||||||
if (graph[index (i, k)] == 1)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
|
|
||||||
j = 0;
|
|
||||||
while (j < nodes)
|
|
||||||
{
|
|
||||||
if (graph[index (k, j)] == 1)
|
|
||||||
{
|
|
||||||
if (i == j)
|
|
||||||
{
|
|
||||||
// Oh no! A cycle.
|
|
||||||
graph[index (i, j)] = 2;
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (DEBUGL (5))
|
|
||||||
{
|
|
||||||
graph_display (graph, nodes);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
graph[index (i, j)] = 1;
|
|
||||||
}
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
k++;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Determine ranks for all nodes
|
|
||||||
/**
|
|
||||||
* Some crude algorithm I sketched on the blackboard.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
graph_ranks (int *graph, int *ranks, int nodes)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int todo;
|
|
||||||
int rank;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while (i < nodes)
|
|
||||||
{
|
|
||||||
ranks[i] = INT_MAX;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
todo = nodes;
|
|
||||||
rank = 0;
|
|
||||||
while (todo > 0)
|
|
||||||
{
|
|
||||||
// There are still unassigned nodes
|
|
||||||
int n;
|
|
||||||
|
|
||||||
n = 0;
|
|
||||||
while (n < nodes)
|
|
||||||
{
|
|
||||||
if (ranks[n] == INT_MAX)
|
|
||||||
{
|
|
||||||
// Does this node have incoming stuff from stuff with equal rank or higher?
|
|
||||||
int refn;
|
|
||||||
|
|
||||||
refn = 0;
|
|
||||||
while (refn < nodes)
|
|
||||||
{
|
|
||||||
if (ranks[refn] >= rank
|
|
||||||
&& graph[graph_index (refn, n)] != 0)
|
|
||||||
refn = nodes + 1;
|
|
||||||
else
|
|
||||||
refn++;
|
|
||||||
}
|
|
||||||
if (refn == nodes)
|
|
||||||
{
|
|
||||||
ranks[n] = rank;
|
|
||||||
todo--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
rank++;
|
|
||||||
}
|
|
||||||
return rank;
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,48 @@
|
|||||||
// Header file for warshall.c
|
/***********************************************************************/
|
||||||
|
/* Based on public-domain code from Berkeley Yacc */
|
||||||
|
|
||||||
void graph_fill (int *graph, int nodes, int value);
|
#include <assert.h>
|
||||||
int warshall (int *graph, int nodes);
|
#include <ctype.h>
|
||||||
int graph_ranks (int *graph, int *ranks, int nodes);
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* machine-dependent definitions */
|
||||||
|
/* the following definitions are for the Tahoe */
|
||||||
|
/* they might have to be changed for other machines */
|
||||||
|
|
||||||
|
/* MAXCHAR is the largest unsigned character value */
|
||||||
|
/* MAXSHORT is the largest value of a C short */
|
||||||
|
/* MINSHORT is the most negative value of a C short */
|
||||||
|
/* MAXTABLE is the maximum table size */
|
||||||
|
/* BITS_PER_WORD is the number of bits in a C unsigned */
|
||||||
|
/* WORDSIZE computes the number of words needed to */
|
||||||
|
/* store n bits */
|
||||||
|
/* BIT returns the value of the n-th bit starting */
|
||||||
|
/* from r (0-indexed) */
|
||||||
|
/* SETBIT sets the n-th bit starting from r */
|
||||||
|
|
||||||
|
#define MAXCHAR UCHAR_MAX
|
||||||
|
#define MAXSHORT SHRT_MAX
|
||||||
|
#define MINSHORT SHRT_MIN
|
||||||
|
#define MAXTABLE 32500
|
||||||
|
|
||||||
|
#define BITS_PER_WORD (8*sizeof(unsigned))
|
||||||
|
#define WORDSIZE(n) (((n)+(BITS_PER_WORD-1))/BITS_PER_WORD)
|
||||||
|
#define BIT(r, n) ((((r)[(n)/BITS_PER_WORD])>>((n)%BITS_PER_WORD))&1)
|
||||||
|
#define SETBIT(r, n) ((r)[(n)/BITS_PER_WORD]|=(1<<((n)%BITS_PER_WORD)))
|
||||||
|
|
||||||
|
/* storage allocation macros */
|
||||||
|
|
||||||
|
#define CALLOC(k,n) (calloc((unsigned)(k),(unsigned)(n)))
|
||||||
|
#define FREE(x) (free((char*)(x)))
|
||||||
|
#define MALLOC(n) (malloc((unsigned)(n)))
|
||||||
|
#define NEW(t) ((t*)allocate(sizeof(t)))
|
||||||
|
#define NEW2(n,t) ((t*)allocate((unsigned)((n)*sizeof(t))))
|
||||||
|
#define REALLOC(p,n) (realloc((char*)(p),(unsigned)(n)))
|
||||||
|
|
||||||
|
/* actual functions */
|
||||||
|
|
||||||
|
void transitive_closure (unsigned int *R, int n);
|
||||||
|
void reflexive_transitive_closure (unsigned int *R, int n);
|
||||||
|
Loading…
Reference in New Issue
Block a user