Implemented well-formedness check as in the 2012 book.

We check that variables occur first in receive events.
This commit is contained in:
Cas Cremers 2012-12-06 09:52:13 +01:00
parent 7a2d354bac
commit 6c7493838c
3 changed files with 59 additions and 111 deletions

View File

@ -2263,62 +2263,74 @@ checkUnusedVariables (const System sys)
} }
} }
//! Is a complete role well-formed //! Is a role well-formed?
/**
* In line with the 2012 book, we check only that variables occur first in
* receives. This is needed to guarantee that the instantiated terms are ground
* (and hence, traces contain run terms).
*
* Returns true if the role is well-formed, false otherwise.
*
* The function outputs its own error messages, but does not (sys.)exit. This
* should be done by the calling function, in order to collect a complete error
* report for all roles.
*/
int int
WellFormedRole (const System sys, Protocol p, Role r) WellFormedRole (const System sys, Protocol p, Role r)
{ {
Knowledge know; Termlist tl;
int okay; int allOkay;
allOkay = true;
for (tl = r->variables; tl != NULL; tl = tl->next)
{
if (!inTermlist (p->rolenames, tl->term))
{
Roledef rd; Roledef rd;
okay = true; rd = firstEventWithTerm (r->roledef, tl->term);
know = emptyKnowledge (); if (rd->type != RECV)
// Transfer inverses {
know->inverses = sys->know->inverses; // Not well-formed
// Add role knowledge globalError++;
knowledgeAddTermlist (know, r->knows); error_pre ();
// Add role names eprintf ("Protocol ");
//@TODO this is not in the semantics as such, often implicit termPrint (p->nameterm);
knowledgeAddTermlist (know, p->rolenames); eprintf (", role ");
// Add local constants termPrint (r->nameterm);
//@TODO this is not in the semantics as such, often implicit eprintf (" is not well-formed: the variable '");
knowledgeAddTermlist (know, r->declaredconsts); termPrint (tl->term);
eprintf ("' should occur first in a receive event.\n");
globalError--;
// Test // Store
rd = r->roledef; allOkay = false;
while (rd != NULL)
{
Knowledge knowres;
knowres = WellFormedEvent (r->nameterm, know, rd);
if (knowres == NULL)
{
okay = false;
break;
}
else
{
know = knowres;
rd = rd->next;
} }
} }
}
// clean up return allOkay;
knowledgeDelete (know);
return okay;
} }
//! Well-formedness check //! Well-formedness check
void void
checkWellFormed (const System sys) checkWellFormed (const System sys)
{ {
int allOkay;
allOkay = true;
int thisRole (Protocol p, Role r) int thisRole (Protocol p, Role r)
{ {
WellFormedRole (sys, p, r); allOkay = allOkay && WellFormedRole (sys, p, r);
return true; return true;
} }
iterateRoles (sys, thisRole); iterateRoles (sys, thisRole);
if (allOkay == false)
{
error
("The protocol specification does not meet the well-formedness condition.");
}
} }
//! Check matching role defs //! Check matching role defs
@ -2542,10 +2554,5 @@ preprocess (const System sys)
/* /*
* Check well-formedness * Check well-formedness
*/ */
/* TODO Temporarily disabled wellformedness check (well-formedness) after Simon bug reporting.
if (sys->knowledgedefined)
{
checkWellFormed (sys); checkWellFormed (sys);
} }
*/
}

View File

@ -459,76 +459,17 @@ wfeError (Knowledge know, Roledef rd, char *errorstring, Term was,
} }
//! Is an event well-formed //! Return the first event (or NULL) in which a term occurs
/** Roledef
* Returns the new knowledge or NULL if it was not well-formed. firstEventWithTerm (Roledef rd, Term t)
*/
Knowledge
WellFormedEvent (Term role, Knowledge know, Roledef rd)
{ {
if (rd == NULL) while (rd != NULL)
{ {
return know; if (termSubTerm (rd->message, t))
{
return rd;
}
rd = rd->next;
} }
if (rd->type == RECV)
{
// Read
if (!isTermEqual (role, rd->to))
{
wfeError (know, rd, "Receiving role incorrect.", rd->to, role);
return NULL;
}
if (!inKnowledge (know, rd->from))
{
wfeError (know, rd, "Unknown sender role.", rd->from, NULL);
return NULL;
}
if (!Readable (know, rd->message))
{
wfeError (know, rd, "Cannot read message pattern.", rd->message,
NULL);
return NULL;
}
knowledgeAddTerm (know, rd->message);
return know;
}
if (rd->type == SEND)
{
// Send
if (!isTermEqual (role, rd->from))
{
wfeError (know, rd, "Sending role incorrect.", rd->from, role);
return NULL;
}
if (!inKnowledge (know, rd->to))
{
wfeError (know, rd, "Unknown receiving role.", rd->to, NULL);
return NULL;
}
if (!inKnowledge (know, rd->message))
{
wfeError (know, rd, "Unable to construct message.", rd->message,
NULL);
return NULL;
}
return know;
}
if (rd->type == CLAIM)
{
// Claim
if (!isTermEqual (role, rd->from))
{
wfeError (know, rd, "Claiming role incorrect.", rd->from, role);
return NULL;
}
return know;
}
// Unknown, false
globalError++;
roledefPrint (rd);
globalError--;
error ("I don't know this event");
return NULL; return NULL;
} }

View File

@ -188,6 +188,6 @@ int roledef_iterate_events (Roledef rd, int (*func) ());
int roledef_length (const Roledef rd); int roledef_length (const Roledef rd);
Roledef roledef_shift (Roledef rd, int i); Roledef roledef_shift (Roledef rd, int i);
int roledefSubTerm (Roledef rd, Term tsub); int roledefSubTerm (Roledef rd, Term tsub);
Knowledge WellFormedEvent (Term role, Knowledge know, Roledef rd); Roledef firstEventWithTerm (Roledef rd, Term t);
#endif #endif