scyther/src/term.h
2013-10-05 23:56:12 +01:00

220 lines
6.7 KiB
C

/*
* Scyther : An automatic verifier for security protocols.
* Copyright (C) 2007-2013 Cas Cremers
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef TERMS
#define TERMS
#include "symbol.h"
#include "bool.h"
// type <= LEAF means it's a leaf, nkay?
enum termtypes
{ GLOBAL, VARIABLE, LEAF, ENCRYPT, TUPLE };
//! The most basic datatype in the modelchecker.
/**
* Describes a single term.
*/
struct term
{
/* basic : name,runid
encrypt: op,key
tuple : op,next
*/
//! The type of term.
/**
* \sa GLOBAL, VARIABLE, LEAF, ENCRYPT, TUPLE
*/
int type;
//! Data Type termlist (e.g. agent or nonce)
/** Only for leaves. */
void *stype; // list of types
union
{
int roleVar; //!< only for leaf, arachne engine: role variable flag
int fcall; //!< only for 'encryption' to mark actual function call f(t)
} helper;
//! Substitution term.
/**
* If this is non-NULL, this leaf term is apparently substituted by
* this term.
*/
struct term *subst; // only for variable/leaf, substitution term
union
{
//! Pointer to the symbol for leaves
Symbol symb;
//! Encrypted subterm.
struct term *op;
//! Left-hand side of tuple pair.
struct term *op1;
struct term *next; //!< for alternative memory management
} left;
union
{
//! run identifier for leaves
int runid;
//! Key used to encrypt subterm.
struct term *key;
//! Right-hand side of tuple pair.
struct term *op2;
} right;
};
//! Component macros (left)
#define TermSymb(t) (t->left.symb)
#define TermOp1(t) (t->left.op1)
#define TermOp(t) (t->left.op)
//! Component macros (right)
#define TermRunid(t) (t->right.runid)
#define TermOp2(t) (t->right.op2)
#define TermKey(t) (t->right.key)
//! Flag for term status
extern int rolelocal_variable;
//! Pointer shorthand.
typedef struct term *Term;
void termsInit (void);
void termsDone (void);
Term makeTermEncrypt (Term t1, Term t2);
Term makeTermFcall (Term t1, Term t2);
Term makeTermTuple (Term t1, Term t2);
Term makeTermType (const int type, const Symbol symb, const int runid);
__inline__ Term deVarScan (Term t);
#define realTermLeaf(t) (t != NULL && t->type <= LEAF)
#define realTermTuple(t) (t != NULL && t->type == TUPLE)
#define realTermEncrypt(t) (t != NULL && t->type == ENCRYPT)
#define realTermVariable(t) (t != NULL && (t->type == VARIABLE || (t->type <= LEAF && rolelocal_variable && TermRunid(t) == -3)))
#define substVar(t) ((realTermVariable (t) && t->subst != NULL) ? 1 : 0)
#define deVar(t) ( substVar(t) ? deVarScan(t->subst) : t)
#define isTermLeaf(t) realTermLeaf(deVar(t))
#define isTermTuple(t) realTermTuple(deVar(t))
#define isTermEncrypt(t) realTermEncrypt(deVar(t))
#define isTermVariable(t) realTermVariable(deVar(t))
#ifdef DEBUG
#define isTermEqual(t1,t2) isTermEqualDebug(t1,t2)
int isTermEqualDebug (Term t1, Term t2);
#else
#define isTermEqual1(t1,t2) ((substVar(t1) || substVar(t2)) \
? isTermEqualFn(t1,t2) \
: ( \
(t1 == t2) \
? 1 \
: ( \
(t1 == NULL || t2 == NULL || t1->type != t2->type) \
? 0 \
: ( \
realTermLeaf(t1) \
? isTermEqualFn(t1,t2) \
: ( \
realTermEncrypt(t2) \
? (isTermEqualFn(TermKey(t1), TermKey(t2)) && \
isTermEqualFn(TermOp(t1), TermOp(t2))) \
: (isTermEqualFn(TermOp1(t1), TermOp1(t2)) && \
isTermEqualFn(TermOp2(t1), TermOp2(t2))) \
) \
) \
) \
) \
)
#define isTermEqual2(t1,t2) ((substVar(t1) || substVar(t2)) \
? isTermEqualFn(t1,t2) \
: ( \
(t1 == t2) \
? 1 \
: ( \
(t1 == NULL || t2 == NULL || t1->type != t2->type) \
? 0 \
: ( \
realTermLeaf(t1) \
? isTermEqualFn(t1,t2) \
: ( \
realTermEncrypt(t2) \
? (isTermEqual1(TermKey(t1), TermKey(t2)) && \
isTermEqual1(TermOp(t1), TermOp(t2))) \
: (isTermEqual1(TermOp1(t1), TermOp1(t2)) && \
isTermEqual1(TermOp2(t1), TermOp2(t2))) \
) \
) \
) \
) \
)
#define isTermEqual(t1,t2) isTermEqual2(t1,t2)
#endif
int hasTermVariable (Term term);
int isTermEqualFn (Term term1, Term term2);
int termSubTerm (Term t, Term tsub);
int termInTerm (Term t, Term tsub);
void termPrintCustom (Term term, char *leftvar, char *rightvar, char *lefttup,
char *righttup, char *leftenc, char *rightenc,
void (*callback) (const Term t));
void termPrint (Term term);
void termTuplePrintCustom (Term term, char *leftvar, char *rightvar,
char *lefttup, char *righttup, char *leftenc,
char *rightenc, void (*callback) (const Term t));
void termTuplePrint (Term term);
Term termDuplicate (const Term term);
Term termNodeDuplicate (const Term term);
Term termDuplicateDeep (const Term term);
Term termDuplicateUV (Term term);
void termDelete (const Term term);
void termNormalize (Term term);
Term termRunid (Term term, int runid);
int tupleCount (Term tt);
Term tupleProject (Term tt, int n);
int termSize (Term t);
float termDistance (Term t1, Term t2);
int termOrder (Term t1, Term t2);
int term_iterate (const Term term, int (*leaf) (Term t),
int (*nodel) (Term t), int (*nodem) (Term t),
int (*noder) (Term t));
int term_iterate_deVar (Term term, int (*leaf) (Term t),
int (*nodel) (Term t), int (*nodem) (Term t),
int (*noder) (Term t));
int term_iterate_leaves (const Term t, int (*func) (Term t));
int term_iterate_open_leaves (const Term term, int (*func) (Term t));
void term_rolelocals_are_variables ();
int term_encryption_level (const Term term);
float term_constrain_level (const Term term);
void term_set_keylevels (const Term term);
void termPrintDiff (Term t1, Term t2);
int isLeafNameEqual (Term t1, Term t2);
Term freshTermPrefix (Term prefixterm);
Term intTermPrefix (const int n, Term prefixterm);
int isTermFunctionName (Term t);
Term getTermFunction (Term t);
unsigned int termHidelevel (const Term tsmall, Term tbig);
void termSubstPrint (Term t);
int iterateTermOther (const int myrun, Term t, int (*callback) (Term t));
extern char *RUNSEP; // by default, set to "#"
#endif