/** * Return true if should be pruned * * The termlist 'agentrole' contains subsequences of length 2, the first of which is a agent name, and the second is the role it is performing. * The idea is that once the agent name is assigned, it should not occur again for a different role. * E.g. [ alice, initiator, bob, responder, charlie, ... ] */ int multipleRolePrune (const System sys) { Termlist agentrole; int run; agentrole = NULL; for (run = 0; run < sys->maxruns; run++) { Protocol p; p = sys->runs[run].protocol; if ((p != INTRUDER) && (!isHelperProtocol (p))) { Term rolename; Term agent; Termlist tl; rolename = sys->runs[run].role->nameterm; agent = agentOfRun (sys, run); // Does this agent already occur yet in the list? for (tl = agentrole; tl != NULL; tl = (tl->next)->next) { if (isTermEqual (agent, tl->term)) { if (!isTermEqual (rolename, (tl->next)->term)) { // Same agent, but different role! This is not allowed. termlistDelete (agentrole); // cleanup return true; } } } // Does not occur yet, so add // Note we add the elements in front, so we need to reverse the order agentrole = termlistPrepend (agentrole, rolename); agentrole = termlistPrepend (agentrole, agent); } } termlistDelete (agentrole); return false; }
//! Show initial knowledge void xmlInitialKnowledge (const System sys) { Termlist knowlist; xmlPrint ("<initialknowledge>"); xmlindent++; knowlist = knowledgeSet (sys->know); xmlTermlistPrint (knowlist); termlistDelete (knowlist); xmlindent--; xmlPrint ("</initialknowledge>"); xmlInverses (sys); }
/** * Interesting case: role names are variables here, so they always match. We catch that case by inspecting the variable list. */ int checkRoletermMatch (const Term t1, const Term t2, const Termlist notmapped) { Termlist tl; // simple clause or combined tl = termMguTerm (t1, t2); if (tl == MGUFAIL) { return false; } else { int result; Termlist vl; result = true; // Reset variables termlistSubstReset (tl); // Check variable list etc: should not contain mapped role names vl = tl; while (vl != NULL) { // This term should not be in the notmapped list if (inTermlist (notmapped, vl->term)) { result = false; break; } vl = vl->next; } // Remove list termlistDelete (tl); return result; } }
/** * Try to determine the most general unifier of two terms. * Resulting termlist must be termlistDelete'd. * *@return Returns a list of variables, that were previously open, but are now closed * in such a way that the two terms unify. Returns \ref MGUFAIL if it is impossible. * The termlist should be deleted. * * @TODO this code should be removed, as it duplicates 'unify' code, and is * ill-suited for adaption later on with multiple unifiers. */ Termlist termMguTerm (Term t1, Term t2) { /* added for speed */ t1 = deVar (t1); t2 = deVar (t2); if (t1 == t2) return NULL; if (!(hasTermVariable (t1) || hasTermVariable (t2))) { if (isTermEqual (t1, t2)) { return NULL; } else { return MGUFAIL; } } /* * Distinguish a special case where both are unbound variables that will be * connected, and I want to give one priority over the other for readability. * * Because t1 and t2 have been deVar'd means that if they are variables, they * are also unbound. */ if (realTermVariable (t1) && realTermVariable (t2) && goodsubst (t1, t2)) { /* Both are unbound variables. Decide. * * The plan: t1->subst will point to t2. But maybe we prefer the other * way around? */ if (preferSubstitutionOrder (t2, t1)) { Term t3; // Swappy. t3 = t1; t1 = t2; t2 = t3; } t1->subst = t2; #ifdef DEBUG showSubst (t1); #endif return termlistAdd (NULL, t1); } /* symmetrical tests for single variable. */ if (realTermVariable (t2)) { if (termSubTerm (t1, t2) || !goodsubst (t2, t1)) return MGUFAIL; else { t2->subst = t1; #ifdef DEBUG showSubst (t2); #endif return termlistAdd (NULL, t2); } } if (realTermVariable (t1)) { if (termSubTerm (t2, t1) || !goodsubst (t1, t2)) return MGUFAIL; else { t1->subst = t2; #ifdef DEBUG showSubst (t1); #endif return termlistAdd (NULL, t1); } } /* left & right are compounds with variables */ if (t1->type != t2->type) return MGUFAIL; /* identical compounds */ /* encryption first */ if (realTermEncrypt (t1)) { Termlist tl1, tl2; tl1 = termMguTerm (TermKey (t1), TermKey (t2)); if (tl1 == MGUFAIL) { return MGUFAIL; } else { tl2 = termMguTerm (TermOp (t1), TermOp (t2)); if (tl2 == MGUFAIL) { termlistSubstReset (tl1); termlistDelete (tl1); return MGUFAIL; } else { return termlistConcat (tl1, tl2); } } } /* tupling second non-associative version ! TODO other version */ if (isTermTuple (t1)) { Termlist tl1, tl2; tl1 = termMguTerm (TermOp1 (t1), TermOp1 (t2)); if (tl1 == MGUFAIL) { return MGUFAIL; } else { tl2 = termMguTerm (TermOp2 (t1), TermOp2 (t2)); if (tl2 == MGUFAIL) { termlistSubstReset (tl1); termlistDelete (tl1); return MGUFAIL; } else { return termlistConcat (tl1, tl2); } } } return MGUFAIL; }