2004-07-24 16:05:20 +01:00
|
|
|
/**
|
2006-01-02 21:06:08 +00:00
|
|
|
* @file role.c
|
2004-07-24 16:05:20 +01:00
|
|
|
* \brief role related logic.
|
|
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
2006-03-08 13:58:46 +00:00
|
|
|
#include <string.h>
|
2004-07-24 16:05:20 +01:00
|
|
|
#include <limits.h>
|
2004-07-24 20:07:29 +01:00
|
|
|
#include "term.h"
|
|
|
|
#include "termlist.h"
|
2004-07-24 16:05:20 +01:00
|
|
|
#include "knowledge.h"
|
2004-07-24 16:08:35 +01:00
|
|
|
#include "system.h"
|
2004-07-24 16:05:20 +01:00
|
|
|
#include "debug.h"
|
2004-07-24 20:07:29 +01:00
|
|
|
#include "role.h"
|
2004-07-24 16:05:20 +01:00
|
|
|
|
2004-08-27 11:08:03 +01:00
|
|
|
extern int protocolCount; // from system.c
|
2004-07-24 16:05:20 +01:00
|
|
|
|
|
|
|
//! Allocate memory the size of a roledef struct.
|
|
|
|
Roledef
|
|
|
|
makeRoledef ()
|
|
|
|
{
|
2006-03-08 13:58:46 +00:00
|
|
|
return (Roledef) malloc (sizeof (struct roledef));
|
2004-07-24 16:05:20 +01:00
|
|
|
}
|
|
|
|
|
2004-07-29 15:47:46 +01:00
|
|
|
//! Print a role event.
|
2004-10-28 13:56:13 +01:00
|
|
|
/**
|
|
|
|
* If print_actor is true, the actor is included (OS version), otherwise it is left out (short stuff)
|
|
|
|
*/
|
2004-07-24 16:05:20 +01:00
|
|
|
void
|
2004-10-28 13:56:13 +01:00
|
|
|
roledefPrintGeneric (Roledef rd, int print_actor)
|
2004-07-24 16:05:20 +01:00
|
|
|
{
|
|
|
|
if (rd == NULL)
|
|
|
|
{
|
2004-07-29 15:47:46 +01:00
|
|
|
eprintf ("[Empty roledef]");
|
2004-07-24 16:05:20 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (rd->type == READ && rd->internal)
|
|
|
|
{
|
|
|
|
/* special case: internal read == choose ! */
|
2004-07-29 15:47:46 +01:00
|
|
|
eprintf ("CHOOSE(");
|
2004-07-24 16:05:20 +01:00
|
|
|
termPrint (rd->message);
|
2004-07-29 15:47:46 +01:00
|
|
|
eprintf (")");
|
2004-07-24 16:05:20 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (rd->type == READ)
|
2004-07-29 15:47:46 +01:00
|
|
|
eprintf ("READ");
|
2004-07-24 16:05:20 +01:00
|
|
|
if (rd->type == SEND)
|
2004-07-29 15:47:46 +01:00
|
|
|
eprintf ("SEND");
|
2004-07-24 16:05:20 +01:00
|
|
|
if (rd->type == CLAIM)
|
2004-07-29 15:47:46 +01:00
|
|
|
eprintf ("CLAIM");
|
2004-07-24 16:05:20 +01:00
|
|
|
if (rd->label != NULL)
|
|
|
|
{
|
2004-08-27 11:08:03 +01:00
|
|
|
//! Print label
|
|
|
|
Term label;
|
|
|
|
|
2005-02-21 15:12:59 +00:00
|
|
|
/* Old version: sometimes prints protocol stuff (really unique labels)
|
2005-06-02 10:40:05 +01:00
|
|
|
label = deVar (rd->label);
|
|
|
|
if (protocolCount < 2 && realTermTuple (label))
|
|
|
|
{
|
|
|
|
// Only one protocol, so we don't need to show the extra label info
|
|
|
|
label = TermOp2 (label);
|
|
|
|
}
|
|
|
|
*/
|
2004-08-27 11:08:03 +01:00
|
|
|
label = deVar (rd->label);
|
2005-02-21 15:12:59 +00:00
|
|
|
if (realTermTuple (label))
|
|
|
|
{
|
|
|
|
label = TermOp2 (label);
|
|
|
|
}
|
2004-08-27 11:08:03 +01:00
|
|
|
|
2006-03-08 13:58:46 +00:00
|
|
|
eprintf ("_");
|
|
|
|
termPrint (label);
|
2004-07-24 16:05:20 +01:00
|
|
|
}
|
2004-07-29 15:47:46 +01:00
|
|
|
eprintf ("(");
|
2004-08-28 10:24:30 +01:00
|
|
|
if (!(rd->from == NULL && rd->to == NULL))
|
|
|
|
{
|
2004-10-28 13:56:13 +01:00
|
|
|
if (print_actor || rd->type == READ)
|
|
|
|
{
|
2004-11-16 12:07:55 +00:00
|
|
|
termPrint (rd->from);
|
|
|
|
eprintf (",");
|
2004-10-28 13:56:13 +01:00
|
|
|
}
|
2004-08-28 10:24:30 +01:00
|
|
|
if (rd->type == CLAIM)
|
|
|
|
eprintf (" ");
|
2004-10-28 13:56:13 +01:00
|
|
|
if (print_actor || rd->type != READ)
|
|
|
|
{
|
|
|
|
termPrint (rd->to);
|
|
|
|
eprintf (", ");
|
|
|
|
}
|
2004-08-28 10:24:30 +01:00
|
|
|
}
|
2004-07-24 16:05:20 +01:00
|
|
|
termPrint (rd->message);
|
2004-07-29 15:47:46 +01:00
|
|
|
eprintf (" )");
|
2004-07-24 16:05:20 +01:00
|
|
|
}
|
|
|
|
|
2006-01-02 21:06:08 +00:00
|
|
|
//! Print a roledef
|
2004-10-28 13:56:13 +01:00
|
|
|
void
|
|
|
|
roledefPrint (Roledef rd)
|
|
|
|
{
|
|
|
|
roledefPrintGeneric (rd, 1);
|
|
|
|
}
|
|
|
|
|
2006-01-02 21:06:08 +00:00
|
|
|
//! Print a roledef, but shorten it
|
2004-10-28 13:56:13 +01:00
|
|
|
void
|
|
|
|
roledefPrintShort (Roledef rd)
|
|
|
|
{
|
|
|
|
roledefPrintGeneric (rd, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-24 16:05:20 +01:00
|
|
|
//! Duplicate a single role event node.
|
|
|
|
/**
|
|
|
|
*\sa roledefDelete()
|
|
|
|
*/
|
|
|
|
Roledef
|
|
|
|
roledefDuplicate1 (const Roledef rd)
|
|
|
|
{
|
|
|
|
Roledef newrd;
|
|
|
|
|
|
|
|
if (rd == NULL)
|
|
|
|
return NULL;
|
|
|
|
newrd = makeRoledef ();
|
|
|
|
memcpy (newrd, rd, sizeof (struct roledef));
|
|
|
|
newrd->next = NULL;
|
|
|
|
return newrd;
|
|
|
|
}
|
2004-08-09 11:05:58 +01:00
|
|
|
|
2004-07-24 16:05:20 +01:00
|
|
|
//! Duplicate a role event list.
|
|
|
|
/**
|
|
|
|
*\sa roledefDelete()
|
|
|
|
*/
|
|
|
|
Roledef
|
|
|
|
roledefDuplicate (Roledef rd)
|
|
|
|
{
|
|
|
|
Roledef newrd;
|
|
|
|
|
|
|
|
if (rd == NULL)
|
|
|
|
return NULL;
|
|
|
|
newrd = roledefDuplicate1 (rd);
|
|
|
|
newrd->next = roledefDuplicate (rd->next);
|
|
|
|
return newrd;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Delete a role event or event list.
|
|
|
|
/**
|
|
|
|
*\sa roledefDuplicate()
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
roledefDelete (Roledef rd)
|
|
|
|
{
|
|
|
|
if (rd == NULL)
|
|
|
|
return;
|
|
|
|
roledefDelete (rd->next);
|
2006-03-08 13:58:46 +00:00
|
|
|
free (rd);
|
2004-07-24 16:05:20 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Destroy a role event or event list.
|
|
|
|
void
|
|
|
|
roledefDestroy (Roledef rd)
|
|
|
|
{
|
|
|
|
if (rd == NULL)
|
|
|
|
return;
|
|
|
|
roledefDestroy (rd->next);
|
|
|
|
termDelete (rd->from);
|
|
|
|
termDelete (rd->to);
|
|
|
|
termDelete (rd->message);
|
2006-03-08 13:58:46 +00:00
|
|
|
free (rd);
|
2004-07-24 16:05:20 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Make a new role event with the specified parameters.
|
|
|
|
/**
|
|
|
|
*@return A pointer to a new role event with the given parameters.
|
|
|
|
*/
|
|
|
|
Roledef
|
|
|
|
roledefInit (int type, Term label, Term from, Term to, Term msg, Claimlist cl)
|
|
|
|
{
|
|
|
|
Roledef newEvent;
|
|
|
|
|
|
|
|
newEvent = makeRoledef ();
|
|
|
|
newEvent->internal = 0;
|
|
|
|
newEvent->type = type;
|
|
|
|
newEvent->label = label;
|
|
|
|
newEvent->from = from;
|
|
|
|
newEvent->to = to;
|
|
|
|
newEvent->message = msg;
|
|
|
|
newEvent->forbidden = NULL; // no forbidden stuff
|
|
|
|
newEvent->knowPhase = -1; // we haven't explored any knowledge yet
|
|
|
|
newEvent->claiminfo = cl; // only for claims
|
2004-08-15 13:24:27 +01:00
|
|
|
if (type == READ)
|
|
|
|
newEvent->bound = 0; // bound goal (Used for arachne only). Technically involves choose events as well.
|
|
|
|
else
|
|
|
|
newEvent->bound = 1; // other stuff does not need to be bound
|
2004-07-24 16:05:20 +01:00
|
|
|
newEvent->next = NULL;
|
|
|
|
return newEvent;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Add a role event to an existing list, with the given parameters.
|
|
|
|
/**
|
|
|
|
*\sa roledefInit()
|
|
|
|
*/
|
|
|
|
Roledef
|
2004-08-09 11:05:58 +01:00
|
|
|
roledefAdd (Roledef rd, int type, Term label, Term from, Term to, Term msg,
|
|
|
|
Claimlist cl)
|
2004-07-24 16:05:20 +01:00
|
|
|
{
|
|
|
|
Roledef scan;
|
|
|
|
|
|
|
|
if (rd == NULL)
|
|
|
|
return roledefInit (type, label, from, to, msg, cl);
|
|
|
|
|
|
|
|
scan = rd;
|
|
|
|
while (scan->next != NULL)
|
|
|
|
scan = scan->next;
|
|
|
|
scan->next = roledefInit (type, label, from, to, msg, cl);
|
|
|
|
return rd;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Create an empty role structure with a name.
|
|
|
|
Role
|
|
|
|
roleCreate (Term name)
|
|
|
|
{
|
|
|
|
Role r;
|
|
|
|
|
2006-03-08 13:58:46 +00:00
|
|
|
r = malloc (sizeof (struct role));
|
2004-07-24 16:05:20 +01:00
|
|
|
r->nameterm = name;
|
2004-08-12 14:22:49 +01:00
|
|
|
r->roledef = NULL;
|
2004-07-24 16:05:20 +01:00
|
|
|
r->locals = NULL;
|
2004-08-12 10:14:31 +01:00
|
|
|
r->variables = NULL;
|
2005-12-27 13:44:12 +00:00
|
|
|
r->declaredvars = NULL;
|
2005-12-28 11:50:17 +00:00
|
|
|
r->declaredconsts = NULL;
|
2005-09-09 11:05:29 +01:00
|
|
|
r->initiator = 1; //! Will be determined later, if a read is the first action (in compiler.c)
|
2006-01-02 16:05:53 +00:00
|
|
|
r->singular = false; // by default, a role is not singular
|
2004-08-12 14:22:49 +01:00
|
|
|
r->next = NULL;
|
2004-07-24 16:05:20 +01:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Print a role.
|
|
|
|
void
|
|
|
|
rolePrint (Role r)
|
|
|
|
{
|
|
|
|
Roledef rd;
|
|
|
|
|
|
|
|
if (r == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
indent ();
|
2004-07-29 15:47:46 +01:00
|
|
|
eprintf ("[[Role : ");
|
2004-07-24 16:05:20 +01:00
|
|
|
termPrint (r->nameterm);
|
2004-07-29 15:47:46 +01:00
|
|
|
eprintf ("]]\n");
|
2004-07-24 16:05:20 +01:00
|
|
|
locVarPrint (r->locals);
|
|
|
|
|
|
|
|
rd = r->roledef;
|
|
|
|
while (rd != NULL)
|
|
|
|
{
|
|
|
|
roledefPrint (rd);
|
2004-07-29 15:47:46 +01:00
|
|
|
eprintf ("\n");
|
2004-07-24 16:05:20 +01:00
|
|
|
rd = rd->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Print a list of roles.
|
|
|
|
void
|
|
|
|
rolesPrint (Role r)
|
|
|
|
{
|
|
|
|
if (r == NULL)
|
|
|
|
{
|
2004-07-29 15:47:46 +01:00
|
|
|
eprintf ("Empty role.");
|
2004-07-24 16:05:20 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while (r != NULL)
|
|
|
|
{
|
|
|
|
rolePrint (r);
|
|
|
|
r = r->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-08-12 10:14:31 +01:00
|
|
|
|
|
|
|
//! Iterate over the events in a roledef list
|
|
|
|
/**
|
|
|
|
* Function gets roledef pointer
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
roledef_iterate_events (Roledef rd, int (*func) ())
|
|
|
|
{
|
|
|
|
while (rd != NULL)
|
|
|
|
{
|
|
|
|
if (!func (rd))
|
|
|
|
return 0;
|
|
|
|
rd = rd->next;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
2004-08-12 12:22:49 +01:00
|
|
|
|
|
|
|
//! Roledef length
|
|
|
|
/**
|
|
|
|
* Would be faster hard-coded,
|
|
|
|
* but this just shows the use of the iteration.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
roledef_length (const Roledef rd)
|
|
|
|
{
|
|
|
|
int count = 0;
|
|
|
|
int countplus (Roledef rd)
|
|
|
|
{
|
|
|
|
count++;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
roledef_iterate_events (rd, countplus);
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Yield roledef pointer for a given index
|
|
|
|
Roledef
|
|
|
|
roledef_shift (Roledef rd, int i)
|
|
|
|
{
|
|
|
|
while (i > 0 && rd != NULL)
|
|
|
|
{
|
|
|
|
rd = rd->next;
|
|
|
|
i--;
|
|
|
|
}
|
|
|
|
return rd;
|
|
|
|
}
|
2006-03-08 15:12:58 +00:00
|
|
|
|
|
|
|
// Check whether a term is a subterm of a roledef
|
|
|
|
int
|
|
|
|
roledefSubTerm (Roledef rd, Term tsub)
|
|
|
|
{
|
|
|
|
if (rd == NULL)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return (termSubTerm (rd->from, tsub) ||
|
|
|
|
termSubTerm (rd->to, tsub) || termSubTerm (rd->message, tsub));
|
|
|
|
}
|
|
|
|
}
|