/*
    mmorph, MULTEXT morphology tool
    Version 2.3, October 1995
    Copyright (c) 1994,1995 ISSCO/SUISSETRA, Geneva, Switzerland
    Dominique Petitpierre, <petitp@divsun.unige.ch>
*/
#ifndef unify_h
#define unify_h

/* size of the array in which the surface string is constructed */
#define MAXUCHAR		((unsigned char) ((1L << BITS(char)) -1))
#define CONCAT_SIZE		MAXUCHAR
/* first part of that array */
#define PREFIX_CONCAT_SIZE	(CONCAT_SIZE/2)
/* rest of that array */
#define SUFFIX_CONCAT_SIZE	(CONCAT_SIZE -  PREFIX_CONCAT_SIZE)

/* impossible value for concat_pos */
#define NO_CONCAT		0

#ifndef lint
typedef enum {
    Goal = 0,
    Lexical,
    Unary,
    Binary,
    Prefix,
    Suffix,
/*
    Compound,
    Composite_prefix,
    Composite_suffix,
*/
    _last_rule_kind
}           e_rule_kind;

#else
/* use defines to shutup lint */
#define Goal		0
#define Lexical		1
#define Unary		2
#define Binary		3
#define Prefix		4
#define Suffix		5
#define _last_rule_kind 6
typedef int e_rule_kind;

#endif	/* ! lint */

#ifndef lint
typedef enum {
    Optional = 0,
    Coerce,
    Obligatory,
    _last_spell_kind
}           e_spell_kind;

#else
#define    Optional		0
#define    Coerce		1
#define    Obligatory		2
#define    _last_spell_kind	3
typedef int e_spell_kind;

#endif	/* ! lint */


typedef unsigned long t_value;

typedef struct {
    t_index     local_index;
    t_index     foreign_index;
}           s_var_map;

typedef struct {
    t_index     type;
    t_value    *att_list;
    s_var_map **var_map;
}           s_tfs;

typedef struct rule_instance_s {
    e_rule_kind rule_kind;
    struct symbol_s *rule_link;
    struct rule_instance_s *branch;
    s_tfs      *lhs;
    s_tfs      *first;
    s_tfs      *second;
    t_letter   *lex;
    t_card      lex_length;
    t_letter   *base_lex;
}           s_rule_instance;

typedef struct {
    struct symbol_s *spell_link;
    e_spell_kind kind;
    s_chain    *constraint;
    t_card      constraint_card;
    s_chain    *left_context;
    t_card      left_context_length;
    s_chain    *focus;
    t_card      focus_length;
    s_chain    *right_context;
    t_card      right_context_length;
    t_card      concat_pos;
}           s_spell_instance;

typedef struct {
    s_rule_instance *tree;
    t_letter   *lex;
    t_card      prefix_length;
    t_card      suffix_length;
    t_card      tfs_index;
}           s_affix_tree;

extern s_chain *build_affix_trees();
extern void generate_surface();
extern void free_affix_tree();
extern void prepare_rules();
extern t_boolean match_tfs();
extern t_boolean subsume_tfs();
extern s_tfs *get_tfs();
extern int  goal_card;
extern t_letter concatenation[];
extern t_index largest_type;

#endif	/* unify_h */
