Rati Gelashvili reported a rare but annoying bug in the hash function handling.

The fix requires a significant reworking of the function handling. This
is a first attempt.

Conflicts:
	src/knowledge.c
	src/knowledge.h

Regression test suggests that the Hashfunction fix works.
This commit is contained in:
Cas Cremers
2013-04-26 11:36:41 +02:00
parent 4a1898db92
commit 7658644295
27 changed files with 225 additions and 226 deletions

View File

@@ -24,6 +24,7 @@
#include "debug.h"
#include "error.h"
#include "switches.h"
#include "knowledge.h"
/*
* Shared stuff
@@ -618,68 +619,6 @@ termlistLength (Termlist tl)
return i;
}
//! Give the inverse key term of a term.
/**
* Gives a duplicate of the inverse Key of some term (which is used to encrypt something), as is defined
* by the termlist, which is a list of key1,key1inv, key2, key2inv, etc...
*@param inverses The list of inverses, typically from the knowledge.
*@param key Any term of which the inverse will be determined.
*@return A pointer to a duplicate of the inverse key term. Use termDelete to remove it.
*\sa termDuplicate(), knowledge::inverses
*/
Term
inverseKey (Termlist inverses, Term key)
{
key = deVar (key);
/* is this a function application? i.e. hash? */
if (isTermLeaf (key) && inTermlist (key->stype, TERM_Function))
{
/* functions cannot be inverted by default */
return termDuplicate (TERM_Hidden);
}
/* check for the special case first: when it is effectively a function application */
if (isTermEncrypt (key) && isTermLeaf (TermKey (key))
&& inTermlist (deVar (TermKey (key))->stype, TERM_Function))
{
/* we are scanning for functions */
/* scan the list */
/* key is function application kk(op), or {op}kk */
Term funKey (Term orig, Term newk)
{
/* in: {op}kk, nk
* out: {op'}nk */
return makeTermEncrypt (termDuplicate (TermOp (orig)),
termDuplicate (newk));
}
while (inverses != NULL && inverses->next != NULL)
{
if (isTermEqual (TermKey (key), inverses->term))
return funKey (key, inverses->next->term);
if (isTermEqual (TermKey (key), inverses->next->term))
return funKey (key, inverses->term);
inverses = inverses->next->next;
}
}
else
{
/* scanning for a direct inverse */
/* scan the list */
while (inverses != NULL && inverses->next != NULL)
{
if (isTermEqual (key, inverses->term))
return termDuplicate (inverses->next->term);
if (isTermEqual (key, inverses->next->term))
return termDuplicate (inverses->term);
inverses = inverses->next->next;
}
}
return termDuplicate (key); /* defaults to symmetrical */
}
//! Create a term local to a run.
/*
* We assume that at this point, no variables have been instantiated yet that occur in this term.