
/* start O5C_H */

/* start DL_LIST_DEF */

struct dll_entry {
	struct dll_entry *next;
	struct dll_entry *prev;
};

typedef struct dll_entry	DLL_Entry;

typedef DLL_Entry * List;

#define SORTED		1
#define UNSORTED	2
#define HEAD		3
#define TAIL		4


extern void ReInitList();
extern DLL_Entry *FindNode();
extern void InsertNode();
extern void RemoveNode();
extern int CopyList();
extern void UnlinkNode();

#define NextNode(node)		((node)->next)
#define PrevNode(node)		((node)->prev)


/* start HASH_TAB_DEF */

typedef DLL_Entry HT_Entry_Header;

struct hash_tab {
	int ht_size;
	int scan_bucket;
	HT_Entry_Header *scan_entry;
	HT_Entry_Header *bucket[1];
};

typedef struct hash_tab *	HashTable;

typedef struct {
	HT_Entry_Header link;
	long key;
} Std_Bucket_Entry;


extern void InitHashTable();
extern HashTable MakeHashTable();
extern HT_Entry_Header *FindEntry();
extern void AddEntry();
extern void RemoveEntry();
extern void ResetHTScan();
extern HT_Entry_Header *ScanHT();

#define RemoveHTEntry(node)		RemoveNode(node)


/* start DYN_MEM_H */

struct String {
	long use_count;
	char strg[1];
};

/* start DYN_MEM_DEF */

typedef struct String *		StrID;

extern StrID StrAlloc();
extern void StrFree();

/* start TYPES_H */

#define USHORT unsigned short
#define BOOLEAN int
#define ULONG unsigned long
#define PTR char *
#define BYTE unsigned char
#define UBYTE unsigned char
#define UCHAR unsigned char

#define TRUE		(-1)
#define FALSE		(0)

#include <stdio.h>

typedef union {
		StrID string;
		int ival;
		float fval;
		FILE *file;
	} Data;

typedef long TimeTag;

/* start WME_H */

struct attribute {
	UBYTE type;
	Data data;
};

struct wme {
	TimeTag time;
	int class_index;
	int inst_ref_cnt;
	PTR del_list;
	USHORT attr_cnt;
	struct attribute attr[1];
};


/* start WME_DEF */

typedef struct attribute *	AttrID;
typedef struct wme *		WmeID;

#define MAX_WME_ATTR		128

#define UNKNOWN_CLASS		(-1)
#define NULL_CLASS		(-2)
#define ALL_CLASS		(-3)

extern WmeID CreateWme();
extern int MatchClass();
extern AttrID SetWmeAttr();
extern void RemoveWme();
extern void SetNil();
extern void PrintWme();

#define ClearWme(wme_id)		SetNil(wme_id->attr,wme_id->attr_cnt)

#define GetWmeClass(wme_id)		(wme_id->class_index)

#define SetWmeClass(index)		wme_id->class_index = index

#define GetWmeAttr(wme_id,offset)	wme_id->attr[offset]

#define GetWmeAttrID(wme_id,offset)	(&(wme_id->attr[offset]))

#define GetAttrType(attr_id)		((attr_id)->type)

#define SetAttrType(attr_id,attr_type)	(attr_id)->type=attr_type

#define GetAttrString(attr_id)		GetString((attr_id)->data.string)

#define GetAttrStrID(attr_id)		((attr_id)->data.string)

#define SetAttrStrID(attr_id,str_id)	(attr_id)->data.string=str_id

#define GetAttrInteger(attr_id)		((attr_id)->data.ival)

#define SetAttrInteger(attr_id,inum)	(attr_id)->data.ival=inum

#define GetAttrFloat(attr_id)		((attr_id)->data.fval)

#define SetAttrFloat(attr_id,fnum)	(attr_id)->data.fval=fnum

#define GetTimeTag(wme_id)		(wme_id->time)

#define SetTimeTag(wme_id,value)	wme_id->time=value

/* back to types.h */

typedef struct attribute Attr;

typedef Attr Atom;

#define AT_FILE			'\000'
#define AT_FLOAT		'\002'
#define AT_INTEGER		'\003'
#define AT_SYMBOL		'\005'
#define AT_FLOAT_ATOM		'\006'
#define AT_INTEGER_ATOM		'\007'

#define is_at_numeric(x)		((x & '\002') == '\002')
#define is_at_symbolic(x)		((x & '\004') == '\004')

extern char *malloc();
extern char *calloc();


/* start ACTION_DEF */

extern void AddExecQ();
extern void RemoveExecQ();
extern int FetchExecQ();
extern void AddRemoveQ();
extern void AddRemoveQ2();
extern WmeID FetchRemoveQ();
extern void PrintAtom();
extern int GetPosNum();
extern void Rjust();
extern void Tabto();
extern void ColumnUpdate();

extern FILE *Openfile();
extern void Closefile();
extern BOOLEAN Default();
extern void rhs_openfile();
extern void rhs_closefile();
extern void rhs_default();
extern void Halt();

#define Remove(ce)	AddRemoveQ(ce)
#define EXEC_Q_EMPTY		(-1)
#define IGNORE			(-1)


/* start AMEM_DEF */

typedef struct {
	DLL_Entry link;
	PTR rlink;
	PTR mem;
	WmeID wme_id;
} AMem_Entry;

struct alpha_mem {
	int rule;
	int count;
	int ra_offset;
	ULONG rule_active_mask;
	void (*join_code)();
	AMem_Entry *mem_list;
	AMem_Entry *scan_ptr;
#ifndef NO_TAIL_PTR
	AMem_Entry *tail;
#endif
};

typedef struct alpha_mem *		AMemID;


extern void AddAMemEntry();
extern void RemoveAMemEntry();
extern void ClearAMem();
extern WmeID scan_amem();

#ifndef NO_TAIL_PTR
#define InitAMem(mem) \
	(ReInitList(&((mem)->mem_list)), \
	(mem)->tail = NULL, \
	(mem)->scan_ptr = NULL)
#else
#define InitAMem(mem) \
	(ReInitList(&((mem)->mem_list)), \
	(mem)->scan_ptr = NULL)
#endif

#define SetMask(mem) \
	(mem)->scan_ptr = (mem)->mem_list

#define Retrieve(mem) \
	((WmeID) ((mem)->scan_ptr ? \
		(wme_id = (mem)->scan_ptr->wme_id, \
		(mem)->scan_ptr = (AMem_Entry *) (mem)->scan_ptr->link.next, \
		wme_id) \
	: NULL))



/* start AMATH_DEF */

extern void plus();
extern void minus();
extern void mult();
extern void div();
extern void mod();

extern Attr a_stack[];
extern int as_ptr;


/* start INST_H */

struct recency {
	TimeTag time;
	USHORT offset;
};

struct instance {
	DLL_Entry link;
	int rule;
	struct recency *time_order;
	USHORT wme_count;
	WmeID elements[1];
};


/* start INST_DEF */

typedef struct instance *	InstID;

extern InstID CreateInst();
extern void AddWme();


/* start CSET_DEF */

extern InstID AddInst();
extern InstID FindInst();
extern InstID GetFirable();
extern void RemoveInst();
extern BOOLEAN lex();
extern BOOLEAN mea();
extern BOOLEAN match_inst();


/* start CTEST_DEF */

extern BOOLEAN eq_float();
extern BOOLEAN eq_int();
extern BOOLEAN eq_symbol();
extern BOOLEAN ne_float();
extern BOOLEAN ne_int();
extern BOOLEAN ne_symbol();
extern BOOLEAN gt_float();
extern BOOLEAN gt_int();
extern BOOLEAN lt_float();
extern BOOLEAN lt_int();
extern BOOLEAN ge_float();
extern BOOLEAN ge_int();
extern BOOLEAN le_float();
extern BOOLEAN le_int();

#define is_symbol(sym)	is_at_symbolic(sym)


/* start STRINGS_DEF */

typedef struct {
	HT_Entry_Header link;
	StrID str_id;
} String_HT_Header;

typedef struct {
	HT_Entry_Header link;
	StrID str_id;
	ULONG SC_offset;
} CT_String_HT_Header;


typedef String_HT_Header *StringEntry;
typedef HashTable StringSpace;

extern StringEntry AddString();
extern StringEntry StringAvail();
extern void ST_Dump();

#define MakeStringTable(count)	((StringSpace) MakeHashTable(count))
#define ResetSTScan		ResetHTScan
#define ScanST(table)		((StringEntry) ScanHT(table))
#define RemoveString(node)	(RemoveHTEntry(node))
#define GetString(strid)	(((StrID)strid)->strg)


/* start DOLLAR_DEF */

struct attr_info {
	String_HT_Header st_head;
	UBYTE offset;
};

extern void dollar_tab2();
extern void dollar_assert();
extern FILE *dollar_ifile();
extern FILE *dollar_ofile();
extern StrID dollar_intern();

#define dollar_parameter(index)	result_element[index-1]
#define dollar_parametercount()	next_re_slot
#define dollar_reset()	(SetNil(result_element,MAX_WME_ATTR),next_re_slot=0)
#define dollar_value(attr)	(result_element[next_re_slot++]=attr)
#define dollar_str_val(value) \
	(result_element[next_re_slot].type=AT_SYMBOL, \
	result_element[next_re_slot++].data.string=((StrID) value))
#define dollar_int_val(value) \
	(result_element[next_re_slot].type=AT_INTEGER, \
	result_element[next_re_slot++].data.ival=value)
#define dollar_flt_val(value) \
	(result_element[next_re_slot].type=AT_INTEGER, \
	result_element[next_re_slot++].fval=value)
#define dollar_tab1(num)	next_re_slot=num-1;

extern int dollar_litbind();
extern BOOLEAN dollar_eql();
extern void dollar_symbol();
extern int dollar_cvan();
extern Attr dollar_cvna();

#define dollar_symbol(x)		(is_at_symbolic(x))
#define NOT_DEFINED	-1


/* start FUNCTION_DEF */

extern void substr();
extern void genatom();
extern void litval();
extern void accept();
extern BOOLEAN acceptline();


/* start JTEST_DEF */

extern BOOLEAN test_eq();
extern BOOLEAN test_ne();
extern BOOLEAN test_gt();
extern BOOLEAN test_ge();
extern BOOLEAN test_lt();
extern BOOLEAN test_le();
extern BOOLEAN test_same();


/* start GLOBALS_DEF */

/**********************************************************************
 * This section contains type declarations for global library variables.
 **********************************************************************/

extern BOOLEAN (*resolution_function)();

extern int resolution_strategy;
#define LEX		0
#define MEA		1

extern BOOLEAN add_to_neg;

/* Sizes of some variable dimensioned arrays */
extern int rule_count;
extern int class_count;
extern int call_entry_count;
extern int attr_count;
extern int amem_count;


/**********************************************************************
 * Result Element structures.
 **********************************************************************/

#define CUR_RE_SLOT	result_element[next_re_slot]

extern Attr result_element[];

extern int next_re_slot;


/**********************************************************************
 * File I/O structures.
 **********************************************************************/

/* The following structures are for keeping track of the files which
 * are open. */

#define NOT_FOUND       0
#define INPUT           1
#define OUTPUT          2

struct file_data {
        String_HT_Header link;
        FILE *fptr;
        int mode;
};

extern StringSpace file_tab;
extern struct file_data *fdptr;

/* File stream identifiers */
#define ACCEPT		0
#define WRITE		1
#define TRACE		2

/* Default file I/O stream pointers */
extern FILE *default_trace;
extern FILE *default_write;
extern FILE *default_accept;
extern FILE *write_file;
extern FILE *t_file;

/* Boolean for transcript file output */
extern BOOLEAN transcript;

extern StringSpace attr_values;


extern BOOLEAN halt_flag;
extern int cycle_count;
extern int delta_cycle_count;


/**********************************************************************
 * Global input buffer for use by top_level, ACCEPT, and ACCEPTLINE.
 **********************************************************************/

#define INPUT_BUFFER_SIZE		512

extern char in_buff[];

extern char *lptr;
extern char quote_chrs[];

extern InstID most_recent;

/**********************************************************************
 * Printing support structures
 **********************************************************************/

#define PBUFF_SIZE		1024

extern char pbuff[];
extern int parg_cnt;

#define PARG_SIZE		20

extern char *parg[];
extern int print_col;

#define PRINT_RESET	parg_cnt = 0; parg[0] = pbuff


/**********************************************************************
 * Statistical monitoring information structures
 **********************************************************************/

/* This array contains restriction masks for some event tests */
extern ULONG restrict[];

/* These structures contain information about activity for each event */
extern struct stat stat_test[];

/* History state variable (name refers to execution stack) */
extern ULONG stack_state;

extern int cnt;
extern FILE *stats_out;
extern USHORT s_addr;
extern ULONG l_addr;


/**********************************************************************
 * Variables needed to run trace file execution of RHS
 **********************************************************************/

extern FILE *trace_input;
extern int trace_file_type;

/* Watch command trace level */
extern int watch_level;

/* Some statistics */
extern int cset_size;
extern int max_cset_size;
extern ULONG cset_avg_total;

extern BOOLEAN arb_select;

/**********************************************************************
 * Global parameter passing block
 **********************************************************************/
#define MAX_FUNC_ARGS	16

extern Attr args[];
extern int fargc;

/* For CBIND.  Set by dollar_assert. */
extern WmeID last_assert;

/* Flags used by pbreak */
extern char *pb_flag;

/*end*/

extern void read_trace();

/**********************************************************************
 * Structure and Preprocessor Definitions
 **********************************************************************/

struct rule_info {
	char *name;
	int first_ce;
	UBYTE ce_count;
	UBYTE test_count;
};

extern struct rule_info rule[];

struct a_print_info {
	StrID str_id;
	int offset;
};

struct class_info {
	char *name;
	UBYTE attr_count;
	struct a_print_info *attr_info;
	AMemID no_test_mem;
	USHORT wme_size;
};

extern struct class_info class[];

struct attr_off {
	String_HT_Header link;
	int offset;
};

extern StringSpace attr_names;


struct call_entry {
	char *name;
	void (*code)();
	char flag;
};

#define CE_ACTION	1
#define CE_FUNCTION	2


#define MAKE_INIT()	\
	next_re_slot = 0;	\
	SetNil(result_element,MAX_WME_ATTR)

#define MAKE_SET_STR_ATTR(attr_type,attr_value)	\
	CUR_RE_SLOT.type = (UBYTE)attr_type;	\
	CUR_RE_SLOT.data.string = (StrID)attr_value

#define MAKE_SET_INT_ATTR(attr_type,attr_value)	\
	CUR_RE_SLOT.type = (UBYTE)attr_type;	\
	CUR_RE_SLOT.data.ival = attr_value

#define MAKE_SET_FLT_ATTR(attr_type,attr_value)	\
	CUR_RE_SLOT.type = (UBYTE)attr_type;	\
	CUR_RE_SLOT.data.fval = attr_value

#define LOCAL_VARS	\
	register WmeID wme_id,gi0,gi1,gi2,gi3;	\
	register InstID inst_id;

#define SET_SCOPE(amem_num,ce_loc)	\
	SetMask(&amem[amem_num]);	\
	while (ce_loc = Retrieve(&amem[amem_num])) {

#define RESET_SCOPE(var_num,ce_loc,attr_offset)	\
	var[var_num] = GetWmeAttr(ce_loc,attr_offset);

#define VTEST(var_num,attr_offset)	\
	var[var_num] = GetWmeAttr(new_wme,attr_offset);

#define TEST(test_name,var_num,ce_loc,attr_offset)	\
	if (!test_name(GetWmeAttr(ce_loc,attr_offset),var[var_num])) \
		continue;

#define STEST(test_name,var_num,attr_offset)	\
	if (!test_name(GetWmeAttr(new_wme,attr_offset),var[var_num])) \
		continue;

#define FUNNEL_1(amem_no) \
	SetMask(&amem[amem_no]); \
	while (wme_id = Retrieve(&amem[amem_no])) { \
		if (

#define FUNNEL_2 \
		) break; \
	} \
	if (wme_id != NULL) \
		continue;


#define FUNNEL_2B \
		) return; \
	}


#define FUNNEL_3(amem_no) \
	SetMask(&amem[amem_no]); \
	if (Retrieve(&amem[amem_no])) \
		continue;


#define FUNNEL_3B(amem_no) \
	SetMask(&amem[amem_no]); \
	if (Retrieve(&amem[amem_no])) \
		return;


#define NEG_CREATE_INST(rule_no,ce_count) \
	global_inst[0] = gi0; \
	global_inst[1] = gi1; \
	global_inst[2] = gi2; \
	global_inst[3] = gi3; \
	if (add_to_neg) { \
		if (inst_id = (InstID) FindNode(CSet[rule_no],match_inst)) \
			RemoveInst(inst_id); \
	} \
	else { \
		inst_id = CreateInst(rule_no); \
		for (count=0; count < ce_count; count++) \
			AddWme(inst_id,global_inst[count],count); \
		AddInst(rule_no,inst_id); \
	}

#define POS_CREATE_INST(rule_no,ce_count) \
	inst_id = CreateInst(rule_no); \
	global_inst[0] = gi0; \
	global_inst[1] = gi1; \
	global_inst[2] = gi2; \
	global_inst[3] = gi3; \
	for (count=0; count < ce_count; count++) \
		AddWme(inst_id,global_inst[count],count); \
	AddInst(rule_no,inst_id);

/**********************************************************************
 * Macros for setting and testing masks in rule_active[] array
 **********************************************************************/

#define BIT_MASK(x)	(1 << x)

#define START_MASK(x)	(x>32 ? ~0 : ~(~0 << x)),(x>32 ? ~(~0 << (x-32)) : 0)

#define NEG_ADD(rule,amem_no) \
	if (rule_active[rule]) { \
		/*printf("(NEG_ADD): Joining rule %d\n",rule);*/ \
		add_to_neg = TRUE; \
		(*amem[amem_no].join_code)(); \
		add_to_neg = FALSE; \
	}

/**********************************************************************
 * Macros for code generated by WRITE
 **********************************************************************/

#define PRINT				fprintf(write_file
#define PRINTD				fprintf(default_write

/* returns AttrID */
#define VAR_ID(ce_offset,attr_offset) \
	&(most_recent->elements[ce_offset]->attr[attr_offset])

/* returns Attr */
#define VAR(ce_offset,attr_offset) \
	most_recent->elements[ce_offset]->attr[attr_offset]

/* returns WmeID */
#define EVAR(ce_offset)	most_recent->elements[ce_offset]

/* Macros used with amath module */
#define POP_STACK		a_stack[as_ptr--]
#define PUSHV(var)		a_stack[++as_ptr] = var
#define PUSHI(integer) \
	a_stack[++as_ptr].type = AT_INTEGER; \
	a_stack[as_ptr].data.ival = integer;
#define PUSHF(flt) \
	a_stack[++as_ptr].type = AT_FLOAT; \
	a_stack[as_ptr].data.fval = flt;


#define JOIN_STAT_BEGIN(arg)
#define JOIN_STAT_END

#ifndef COERCE
#define test_eq(id1,id2) \
	((id1.type==id2.type) && (id1.data.ival==id2.data.ival))

#define test_ne(id1,id2) \
	((id1.type!=id2.type) || (id1.data.ival!=id2.data.ival))
#endif

/**********************************************************************
 * Macros for calling external functions.
 **********************************************************************/
#define VAR_ARG(var_num)	args[fargc++] = var[var_num]

#define PATH_ARG(ce_offset,attr_offset) \
	args[fargc++] = VAR(ce_offset,attr_offset)

#define STR_ARG(addr)	\
	args[fargc].type = AT_SYMBOL;	\
	args[fargc++].data.string = (StrID) addr

#define INT_ARG(value)	\
	args[fargc].type = AT_INTEGER;	\
	args[fargc++].data.ival = value

#define FLT_ARG(value)	\
	args[fargc].type = AT_FLOAT;	\
	args[fargc++].data.fval = value


/* Used for substr function */
#define INF		-1
