Caught Athena problem case.

I've added a marked for the Athena problem case, and now no more false 'complete proof' results are produced.
However, the tool reports, 'no attack within bounds', which is slightly inaccurate
depending on the interpretatio of 'bounds'.
This commit is contained in:
Cas Cremers 2007-09-18 15:27:41 +02:00
parent 6cf81b3e8e
commit 59bcb18fec
4 changed files with 26 additions and 148 deletions

165
src/mgu.c
View File

@ -269,6 +269,8 @@ unify (Term t1, Term t2, Termlist tl, int (*callback) (Termlist))
*
* The callback should return true for the iteration to proceed, or false to abort.
* The final result is this flag.
*
* This is the actual procedure used by the Arachne algorithm in archne.c
*/
int
subtermUnify (Term tbig, Term tsmall, Termlist tl, Termlist keylist,
@ -315,6 +317,26 @@ subtermUnify (Term tbig, Term tsmall, Termlist tl, Termlist keylist,
keylist = termlistDelTerm (keylist);
}
}
// Athena problem case: open variable about to be unified.
/**
* In this case we really need to consider the problematic Athena case for untyped variables.
*/
if (isTermVariable (tbig))
{
// Check the type: can it contain tuples, encryptions?
if (isOpenVariable (tbig))
{
// This one needs to be pursued by further constraint adding
/**
* Currently, this is not implemented yet. TODO.
* This is actually the main Athena problem that we haven't solved yet.
*/
// Mark that we don't have a full proof.
markNoFullProof ();
}
}
return proceed;
}
@ -470,149 +492,6 @@ termMguTerm (Term t1, Term t2)
return MGUFAIL;
}
//! Most general interm unifiers of t1 interm t2
/**
* Try to determine the most general interm unifiers of two terms.
*@returns Nothing. Iteration gets termlist of substitutions.
*/
int
termMguInTerm (Term t1, Term t2, int (*iterator) (Termlist))
{
Termlist tl;
int flag;
flag = 1;
t2 = deVar (t2);
if (t2 != NULL)
{
if (realTermTuple (t2))
{
// t2 is a tuple, consider interm options as well.
flag = flag && termMguInTerm (t1, TermOp1 (t2), iterator);
flag = flag && termMguInTerm (t1, TermOp2 (t2), iterator);
}
// simple clause or combined
tl = termMguTerm (t1, t2);
if (tl != MGUFAIL)
{
// Iterate
flag = flag && iterator (tl);
// Reset variables
termlistSubstReset (tl);
// Remove list
termlistDelete (tl);
}
}
else
{
if (deVar (t1) != NULL)
{
flag = 0;
}
}
return flag;
}
//! Most general subterm unifiers of smallterm subterm bigterm
/**
* Try to determine the most general subterm unifiers of two terms.
*@returns Nothing. Iteration gets termlist of subst, and list of keys needed
* to decrypt. This termlist does not need to be deleted, because it is handled
* by the mguSubTerm itself.
*/
int
termMguSubTerm (Term smallterm, Term bigterm,
int (*iterator) (Termlist, Termlist), Termlist inverses,
Termlist cryptlist)
{
int flag;
flag = 1;
smallterm = deVar (smallterm);
bigterm = deVar (bigterm);
if (bigterm != NULL)
{
Termlist tl;
if (!realTermLeaf (bigterm))
{
if (realTermTuple (bigterm))
{
// 'simple' tuple
flag =
flag
&& termMguSubTerm (smallterm, TermOp1 (bigterm), iterator,
inverses, cryptlist);
flag = flag
&& termMguSubTerm (smallterm, TermOp2 (bigterm), iterator,
inverses, cryptlist);
}
else
{
// Must be encryption
Term keyneeded;
keyneeded = inverseKey (inverses, TermKey (bigterm));
// We can never produce the TERM_Hidden key, thus, this is not a valid iteration.
if (!isTermEqual (keyneeded, TERM_Hidden))
{
cryptlist = termlistAdd (cryptlist, bigterm); // Append, so the last encrypted term in the list is the most 'inner' one, and the first is the outer one.
// Recurse
flag =
flag
&& termMguSubTerm (smallterm, TermOp (bigterm), iterator,
inverses, cryptlist);
cryptlist = termlistDelTerm (cryptlist);
}
termDelete (keyneeded);
}
}
else
{
// The big term is a leaf
/**
* In this case we really need to consider the problematic Athena case for untyped variables.
*/
if (isTermVariable (bigterm))
{
// Check the type: can it contain tuples, encryptions?
if (isOpenVariable (bigterm))
{
// This one needs to be pursued by further constraint adding
/**
* Currently, this is not implemented yet. TODO.
* This is actually the main Athena problem that we haven't solved yet.
*/
// Mark that we don't have a full proof.
markNoFullProof ();
}
}
}
// simple clause or combined
tl = termMguTerm (smallterm, bigterm);
if (tl != MGUFAIL)
{
// Iterate
flag = flag && iterator (tl, cryptlist);
// Reset variables
termlistSubstReset (tl);
// Remove list
termlistDelete (tl);
}
}
else
{
if (smallterm != NULL)
{
flag = 0;
}
}
return flag;
}
//! Check if role terms might match in some way
/**
* Interesting case: role names are variables here, so they always match. We catch that case by inspecting the variable list.

View File

@ -33,9 +33,6 @@
#define MGUFAIL (Termlist) -1
Termlist termMguTerm (Term t1, Term t2);
int termMguInTerm (Term t1, Term t2, int (*iterator) (Termlist));
int termMguSubTerm (Term t1, Term t2, int (*iterator) (Termlist, Termlist),
Termlist inverses, Termlist keylist);
void termlistSubstReset (Termlist tl);
int checkRoletermMatch (const Term t1, const Term t2, const Termlist tl);

View File

@ -78,7 +78,9 @@ isTypelistGeneric (const Termlist typelist)
//! Say whether this variable can contain tuples and/or encryptions
/**
* Precondition: tvar should be a variable
* Precondition: tvar should be a variable.
*
* This function is specifically used for detecting the problematic Athena case.
*/
int
isOpenVariable (const Term tvar)

View File

@ -30,6 +30,6 @@ Termlist typelistConjunct (Termlist typelist1, Termlist Typelist2);
int checkAllSubstitutions (const System sys);
int isAgentType (Termlist typelist);
int goodAgentType (Term agent);
int isOpenVariable(const Term tvar);
int isOpenVariable (const Term tvar);
#endif