Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > a89df24b3c34782b2b9adf0ab690227f > files > 61

dyalog-1.11.3-1mdv2008.1.i586.rpm

/* $Id: trail.h 566 2006-11-06 17:20:50Z clerger $
 * Copyright (C) 1996, 2002, 2004, 2006 Eric de la Clergerie
 * ------------------------------------------------------------
 *
 *   Trail -- Implementation of the layer and trail stacks
 *
 * ------------------------------------------------------------
 * Description
 *   Variable bindings are accessed through two stacks
 *      * Layer stack for bindings in DyALog objects
 *      * Trail stack for recent bindings created by unification
 *      or subsumption.
 *
 *   The trail stack is also used to store local and layer trail points
 *   to undo bindings
 *
 * Parameters
 *           LSTACK_SIZE : size of the layer stack
 *            TRAIL_SIZE : size of the trail stack
 * ------------------------------------------------------------
 */

#ifndef TRAIL_READ
#define TRAIL_READ

typedef struct layer_undo_box *layer_undo_t;
typedef struct overwrite_box  *overwrite_t;

/**********************************************************************
 *    Control : Environment and Backtrack
 **********************************************************************/

typedef struct environment_box   *environment_t;
typedef struct choice_box        *choice_t;
typedef void                     (*continuation_t)();

#define R_CP      ((continuation_t) REG(I_CP))
#define R_E       ((environment_t) REG(I_E))
#define R_B       ((choice_t) REG(I_B))
#define R_BC      ((choice_t) REG(I_BC))
#define R_P       ((continuation_t) REG(I_P))

#define R_MIN_LAYER    ((fkey_t) REG(I_MIN_LAYER))


#define  LVALUE_R_CP      (LVALUE_REG(I_CP))
#define  LVALUE_R_E       (LVALUE_REG(I_E))
#define  LVALUE_R_B       (LVALUE_REG(I_B))
#define  LVALUE_R_BC      (LVALUE_REG(I_BC))
#define LVALUE_R_P       (LVALUE_REG(I_P))
#define LVALUE_R_MIN_LAYER    (LVALUE_REG(I_MIN_LAYER))

/**********************************************************************
 *    For the Common Generalizer Operation
 **********************************************************************/

typedef struct cgbinding_box *cgbinding_t;

/**********************************************************************
 *    For the Indexation Operations 
 **********************************************************************/

typedef struct indexation_box *indexation_t;
typedef void *SubsTree;

/**********************************************************************
 *    For Keeping Info about Variable Display
 **********************************************************************/

typedef struct display_box *display_t;

/***********************************************************************
 *    For the Collect and Collapse passes
 ***********************************************************************/

typedef struct collect_list  *collect_t;   /* pointer to a list of collected variables */
typedef struct collapse_box  *collapse_t;  /* pointer to a collapse box */   
typedef struct rename_box    *rename_t;    /* pointer to a rename box   */
typedef struct unbind_box    *unbind_t;    /* pointer to an unbind box  */  
typedef struct binding_box   *binding_t;

#define FOLVAR_HI_SHIFT      5
#define FOLVAR_LO_MASK       ((1 >> FOLVAR_HI_SHIFT) - 1)
#define FOLVAR_HI(X)         (FOLVAR_INDEX(X) >> FOLVAR_HI_SHIFT)
#define FOLVAR_LO_INDEX(X)   (1 << (FOLVAR_INDEX(X)  & FOLVAR_LO_MASK))

#define COLLAPSE_MARK_ENTERED( _layer )				\
     if (! (_layer)->collapse)					\
                { (_layer)->collapse = TRAIL_COLLAPSE(_layer);}

#define TAG_LOCAL_EXITED     1
#define TAG_LAYER_EXITED     2

#define COLLAPSE_MARK_EXITED(_layer)			\
      ((_layer)->collapse->exited |= TAG_LOCAL_EXITED )

#define COLLAPSE_LOCAL_EXITED_P( _collapse )	\
     ( (_collapse)->exited & TAG_LOCAL_EXITED )

#define COLLAPSE_MARK_LAYER_EXITED( _layer )		\
     ((_layer)->collapse->exited |= TAG_LAYER_EXITED )

#define COLLAPSE_LAYER_EXITED_P( _collapse )	\
     ( (_collapse)->exited & TAG_LAYER_EXITED )

/***********************************************************************
 *   Sbinding (Layer bindings)
 ***********************************************************************/

typedef struct sbinding {
  fol_t  bindee;
  long  bindee_shift;
} *sbind_t;

#define SBINDING_SIZE    (sizeof( struct sbinding))

#define SBINDING_MAKE( _v , _k)					\
     ({ sbind_t sbind = (sbind_t) GC_MALLOC( SBINDING_SIZE );	\
        sbind->bindee = _v;					\
	sbind->bindee_shift = _k;				\
	sbind; })

#define SBINDING_K(k,b)							\
     (k = ( b->bindee_shift == 1 )					\
                  ? (fkey_t) 0						\
		  : (k + (b->bindee_shift >> LSTACK_ALIGN_SHIFT)))

/***********************************************************************
 *   Layer stack (for layer bindings)
 ***********************************************************************/

typedef struct layer {
  vca_t    vca;
  long     collect0;                  /* collect X_k with HI(X) == 0 */
  collect_t  collect_list;            /* collect other X_k within a sorted list */
  collapse_t collapse;                /* a pointer to a collapse box in the trail stack */
}  __attribute__ ((aligned (16))) *fkey_t;

extern struct layer  lstack[];

#define LSTACK_BASE         ( (fkey_t) &lstack[0] )
#define LSTACK_INDEX( p )   ( (long) (p - LSTACK_BASE ))
#define LSTACK_POINTER( i ) ( (fkey_t) (LSTACK_BASE + i))
#define LSTACK_TOP          ( (fkey_t) REG(I_LAYER) )
#define LVALUE_LSTACK_TOP          ( LVALUE_REG(I_LAYER) )

#define LSTACK_VCA( i )     ( lstack[i].vca )

#define KEY_TO_BINT( p )    ( BINT( LSTACK_INDEX( p )) )
#define BINT_TO_KEY( i )    ( LSTACK_POINTER( CINT( i )) )


#define LSTACK_PUSH(_top_,_layer)			\
       ( assert( ((fkey_t) _top_) < lstack + LSTACK_SIZE),	\
         ((fkey_t)_top_)->collect0 = 0,				\
	 ((fkey_t)_top_)->collect_list = (collect_t) 0,		\
	 ((fkey_t)_top_)->collapse = (void *) 0,		\
	 ((fkey_t)_top_)->vca      = _layer,			\
	 _top_ = ((fkey_t) _top_) + 1 			\
	 )

#define LSTACK_ALIGN_SHIFT 4   /* the value depends on the asked aligment on layers */
#define LSTACK_ALIGN(   k )   ( (long)(k) << LSTACK_ALIGN_SHIFT )

#define LSTACK_POP( _top ) ( LVALUE_LSTACK_TOP = REG_VALUE(_top) )

#define LAYER_ONCE_DEREF( X, k ) ( vca_ref( k->vca , FOLVAR_INDEX( FOL_DEREF_VAR(X))))

				/* Standard Layer Binding */
#define LAYER_REBIND( _vca, X, k, t, l)				\
     ({long   s = FOL_GROUNDP(t) ? 1 : LSTACK_ALIGN(l-k);	\
       sbind_t bind = SBINDING_MAKE( t, s );			\
       vca_set( _vca, FOLVAR_INDEX( X ), (entry_t) bind );	\
      })

#define LAYER_UNBIND( X, k )  (vca_reset( LSTACK_VCA( k ), FOLVAR_INDEX( X )))

#define LAYER_MERGE(k , l) (LSTACK_VCA( k ) = vca_merge( LSTACK_VCA( k ), LSTACK_VCA( l )))

#define LAYER_LENGTH( k )        (VCA_SAFE_LENGTH( LSTACK_VCA( k ) ))
    
#define LSTACK_PUSH_VOID  (LSTACK_PUSH(LVALUE_LSTACK_TOP,(vca_t) 0), LSTACK_TOP - 1)

/***********************************************************************
 * Trail stack of local bindings (and trail points)
 ***********************************************************************/

typedef enum { CHOICE=0,
	       INDEXATION,
	       LAYER,
	       OVERWRITE,
	       UBIND,
	       SBIND,
	       CGBIND,
	       ENVIRONMENT,
	       COLLAPSE, 
	       UNBIND,
	       RENAME,
	       MASK,
	       COLLECT,
               DISPLAY,
               FORWARD,
               UPWARD,
               HASH_SCAN,
               REGISTERS,
               BLOCK
             } boxtype;

// typedef void * TrailWord;

// typedef WamWord TrailWord;

typedef union trailbox {

    boxtype type;                      /* to access directly the trailbox type */

    struct layer_undo_box {
        boxtype type;                    /* type = LAYER   */
        fkey_t top;                     /* top of layer stack */
    }  layer_undo;
  
    struct binding_box {

        boxtype       type;              /* type = UBIND or SBIND or MASK */

        fkey_t        binder_key;        /* search is done on this key => first position */  

        fol_t         bindee;            /* the binding */
        fkey_t        bindee_key;

        binding_t     next;              /* following binding for binder */
        binding_t    *back;              /* ptr on binder's previous binding next field */

        fol_t         binder;            /* information about the binder (could be removed)  */

        binding_t     keep;              /* next binding to keep (Collapse Pass) */

    } binding;

    struct cgbinding_box {
        boxtype      type;		     /* type = GBIND */
        fol_t        binder;
        fkey_t       k_binder;
        fol_t        left;
        fkey_t       k_left;
        fol_t        right;
        fkey_t       k_right;
        cgbinding_t  next;
    } cgbinding;
    
    struct collapse_box {
        boxtype       type;              /* type = COLLAPSE */
        fkey_t       layer;
        Bool        exited;
        fkey_t       block_start;
        unsigned long         shift;             /* new position after collapse */
        rename_t      rename_list;
        collapse_t    next;
        vca_t         new;               /* new vca */
    } collapse;

    struct unbind_box {
        boxtype       type;             /* type = UNBIND */
        fol_t         Y;                /* Y_l target of at least one renaming */
        fkey_t        l;
        rename_t      rename_list;      /* list of X_k renamed into Y_l */
        unbind_t      next;
    } unbind;

    struct rename_box {
        boxtype       type;              /* type = RENAME */
        fol_t         X;                 /* => X_k renamed */
        fkey_t        k;
        rename_t      next;
    } rename;

    struct indexation_box {
        boxtype      type;              /* type = INDEXATION (not yet used) */
        SubsTree     father;            /* father of the current node in the Subst. tree */
        SubsTree     son;               /* next node to visit in the Subst. tree */
        fkey_t       top;               /* the top layer BEFORE load env. in the layer stack */
        indexation_t back;              /* link with previous index box */
    } indexation;

    struct overwrite_box {
        boxtype type;                    /* type = OVERWRITE (not yet used) */
        fkey_t  key;                     /* The overwriten layer       */
        vca_t  vca;                      /* and its previous vca value */
    } overwrite;

    struct collect_list {
        boxtype   type;		     /*  type = COLLECT            */
        unsigned long     index;
        unsigned long     collect;
        collect_t next;
    } collect;

    struct environment_box {
        boxtype        type;	     /* type = ENVIRONMENT */
        continuation_t cp;
        fkey_t        top;
        TrailWord     *trail;
        fkey_t        min_layer;
        environment_t  prev;
        tabobj_t       trans;
        fkey_t         trans_key;
        tabobj_t       item;
        fkey_t         item_key;
        long           n;
    } environment;

    struct choice_box {
        boxtype        type;             /* type = CHOICE */
        fkey_t        top;              /*   LSTACK_TOP copy */
        TrailWord     *trail;            /*  TRAIL top */
        fkey_t        min_layer;
        continuation_t alt;
        continuation_t cp;
        environment_t  e;
        choice_t       prev;
        choice_t       bc;
        tabobj_t       trans;
        fkey_t         trans_key;
        tabobj_t       item;
        fkey_t         item_key;
        long           n;
    } choice;

    struct display_box {
        boxtype    type;             /* type = DISPLAY */
        fol_t      var;
        fkey_t     key;
        int        status;           /* 0=single occ var, >0 = multi
                                      * occ var */
        char *     name;        /* varname to be displayed if non empty*/
        display_t  next;
    } display;

    struct registers_box {
        boxtype    type;             /*  type = REGISTERS */
        tabobj_t   item;
        fkey_t     k_item;
        fol_t      item_comp;
    } registers;
    
} *bind_t;

extern TrailWord trail[];

#define TRAIL_BASE            ( (TrailWord *) &trail[NB_REGISTERS]  )
#define C_TRAIL_TOP           ( (TrailWord *) REG(I_TRAIL) )
#define C_TRAIL_COLLAPSE      ( (collapse_t )(trail[I_COLLAPSE] ))
#define C_TRAIL_BINDING       ( (binding_t )(trail[I_BINDING] ))
#define C_TRAIL_UNBIND        ( (unbind_t )(trail[I_UNBIND] ))
#define C_TRAIL_CGBINDING     ( (cgbinding_t)(trail[I_CGBINDING] ) )
#define C_TRAIL_DISPLAY       ( (display_t )(trail[I_DISPLAY] ))

#define LVALUE_TRAIL_BASE            ( &trail[NB_REGISTERS]  )
#define LVALUE_C_TRAIL_TOP           ( LVALUE_REG(I_TRAIL) )
#define LVALUE_C_TRAIL_COLLAPSE      ( trail[I_COLLAPSE] )
#define LVALUE_C_TRAIL_BINDING       ( trail[I_BINDING] )
#define LVALUE_C_TRAIL_UNBIND        ( trail[I_UNBIND] )
#define LVALUE_C_TRAIL_CGBINDING     ( trail[I_CGBINDING] )
#define LVALUE_C_TRAIL_DISPLAY       ( trail[I_DISPLAY] )

#define PUSH_TRAIL_BOX(_type,_box)		\
  _type _box = (_type) (C_TRAIL_TOP+1);		\
  LVALUE_C_TRAIL_TOP = REG_VALUE((TrailWord *) (_box+1));		\
  *C_TRAIL_TOP = (TrailWord) _box;		\
  assert( C_TRAIL_TOP < trail + (TRAIL_SIZE));

#define PUSH_TRAIL_VAR_BOX(_type,_box,_n)	\
  _type _box = (_type) (C_TRAIL_TOP+1);		\
  LVALUE_C_TRAIL_TOP = REG_VALUE((TrailWord *) (_box+1) + _n);	\
  *C_TRAIL_TOP = (TrailWord) _box;		\
  assert( C_TRAIL_TOP < trail + (TRAIL_SIZE));

#define PUSH_TRAIL_BLOCK(_n)                            \
({                                                      \
    TrailWord *box=C_TRAIL_TOP+1;                       \
    *(boxtype *)box=BLOCK;                              \
    LVALUE_C_TRAIL_TOP= REG_VALUE(box+(_n/4)+1);                          \
    *C_TRAIL_TOP=(TrailWord)box;                        \
    assert( C_TRAIL_TOP < trail + (TRAIL_SIZE));      \
    box+1;                                              \
})
    
#define POP_TRAIL_BOX(_top)			\
({						\
  bind_t box =   (bind_t) (*(TrailWord *)_top);		\
  _top=((TrailWord *) (*(TrailWord *)_top))-1;		\
  box;						\
})

#define TRAIL_TYPE(_top)      (((bind_t) (*_top))->type)


/***********************************************************************
 * Control stack (use boxtype as trail stack)
 ***********************************************************************/

extern TrailWord c_ctl[];

#define CTL_BASE            ( (TrailWord *) c_ctl  )
#define C_CTL_TOP           ( (TrailWord *) REG(I_CTL) )

#define LVALUE_CTL_BASE            ( c_ctl  )
#define LVALUE_C_CTL_TOP           ( LVALUE_REG(I_CTL) )


#define PUSH_CTL_VAR_BOX(_type,_box,_n)         \
  _type _box = (_type) (C_CTL_TOP+1);           \
  LVALUE_C_CTL_TOP = REG_VALUE((TrailWord *) (_box+1) + _n);      \
  *C_CTL_TOP = (TrailWord) _box;                \
  assert( C_CTL_TOP < c_ctl + (CTL_SIZE));

#define POP_CTL_BOX(_top)                       \
({                                              \
  bind_t box =   (bind_t) (*_top);              \
  _top=((TrailWord *) (*_top))-1;               \
  box;                                          \
})

/***********************************************************************
 *                      Prototypes
 ***********************************************************************/
     
typedef enum { _fail_bind_ = 0, _local_bind_ , _layer_bind_ } bindtype;

				/* Dereferencing  */

extern binding_t once_u_deref    ( const fol_t , const fkey_t );
extern binding_t once_s_deref    ( const fol_t , const fkey_t );
extern binding_t once_l_deref    ( const fol_t , fkey_t );
extern binding_t once_ul_deref   ( const fol_t , fkey_t );
extern binding_t closure_ul_deref( fol_t , fkey_t );
extern Bool      loop_deref      ( fol_t , fkey_t );
				/* Trailing & Untrailing */

extern void  collapse_insert( collapse_t *, collapse_t );
extern void  untrail_layer();

				/* Collecting & Collapsing */

extern void  wrapped_collect(fol_t, fkey_t);
extern obj_t collapse( fol_t, fkey_t);

				/* Term Operations */

extern Bool sfol_occur(fol_t, fkey_t, fol_t, fkey_t);
extern Bool sfol_unify(fol_t, fkey_t, fol_t, fkey_t);
extern Bool sfol_subsume(fol_t, fkey_t, fol_t, fkey_t);
extern Bool sfol_alt_subsume(fol_t, fkey_t, fol_t, fkey_t);
extern Bool sfol_identical(fol_t, fkey_t, fol_t, fkey_t);
extern void sfol_unif_bind(fol_t, fkey_t, fol_t, fkey_t);

extern unsigned long sfol_weight(fol_t, fkey_t);
extern fol_t sfol_copy(fol_t, fkey_t);

/**********************************************************************
 * LAYER entries
 *     Materialize the start of a new environement in the layer stack
 *     (implicitely starts also a new environement in the trail stack)
 **********************************************************************/

#define TSO( _pos )    ((_pos)->layer_undo)

inline static
void TRAIL_LAYER()
{
    PUSH_TRAIL_BOX(layer_undo_t,box);
    box->type = LAYER;
    box->top  = LSTACK_TOP;
}

inline static
void UNTRAIL_LAYER( layer_undo_t box )
{						
    LSTACK_POP( box->top );
}

/**********************************************************************
 * UBIND and SBIND and MASK  entries
 *    Materialize a local unification or subsumption or mask binding
 *
 *   - UBIND : Local Unification Binding
 *   - SBIND : Local Subsumption Binding
 *   - MASK  : Mask a local binding
 **********************************************************************/


#define  TRAIL_UBIND( X, k, t, l)                                               \
     ({                                                                         \
       fol_t _x = FOL_DEREF_VAR(X);                                             \
       binding_t * _b =  (binding_t *) &FOLVAR_UNIF_REF( _x ) ; \
       TRAIL_BIND( UBIND, _x, k, t, l,_b); \
     })

#define  TRAIL_SBIND( X, k, t, l)                                               \
     ({                                                                         \
       fol_t _x = FOL_DEREF_VAR(X);                                             \
       TRAIL_BIND( SBIND, _x, k, t, l, (binding_t *)&FOLVAR_SUB_REF( _x ) ) ; \
     })
    
#define TSB( _pos )      ((_pos)->binding)

inline static
binding_t TRAIL_BIND( boxtype _type,
                      fol_t X, fkey_t k,
                      fol_t t, fkey_t l,
                      binding_t *_b)  
{                                            
    PUSH_TRAIL_BOX(binding_t,box);
    box->type=  _type;                
    box->binder=X;                    
    box->binder_key=k;                
    box->bindee=t;                                     
    box->bindee_key= (FOL_GROUNDP(t)) ? (fkey_t) 0 : l;
    if (k < R_MIN_LAYER) {
        LVALUE_R_MIN_LAYER=REG_VALUE(k);
    }
    box->keep = (binding_t) 0;
    for (; *_b && (*_b)->binder_key > k ; _b = &((*_b)->next) );
    box->next = *_b;                                         
    *_b = (binding_t) box;                                      
    box->back = _b;
    return box;                                                        
}

inline static
void UNTRAIL_BIND_OR_MASK(binding_t box)
{				
    *(box->back) = box->next;	
}

/**********************************************************************
 * GBIND entries
 *    Materialize a binding done when searching a common generalization
 **********************************************************************/

#define TSCG( _pos )  ( (_pos)->cgbinding )

inline static
cgbinding_t TRAIL_CGBIND( fol_t X, fkey_t k,
                          fol_t _left, fkey_t _k_left,
                          fol_t _right, fkey_t _k_right )
{
    PUSH_TRAIL_BOX(cgbinding_t,box);
    box->type     = CGBIND;
    box->binder   = X;
    box->k_binder = k;
    box->left     = _left;
    box->k_left   = _k_left;
    box->right    = _right;
    box->k_right  = _k_right;
    box->next     = C_TRAIL_CGBINDING;
    LVALUE_C_TRAIL_CGBINDING = REG_VALUE(box);
    return box;
}
       
inline static
void UNTRAIL_CGBIND( cgbinding_t box )
{						
    LVALUE_C_TRAIL_CGBINDING = REG_VALUE(box->next);
}

/**********************************************************************
 * COLLAPSE entries
 *    Materialize an entered layer during the collapse pass
 **********************************************************************/

#define TSC( _pos )   ( (_pos)->collapse )

inline static
collapse_t TRAIL_COLLAPSE( fkey_t _layer )
{
    PUSH_TRAIL_BOX(collapse_t,box);
    box->type  = COLLAPSE;		
    box->layer = _layer;		
    box->exited = 0;			
    box->shift  = 0;			
    box->new    = (vca_t) 0;		
    box->rename_list = (rename_t) 0;	
    collapse_insert( (collapse_t *) &LVALUE_C_TRAIL_COLLAPSE, box );
    return box;
}

inline static
void UNTRAIL_COLLAPSE(collapse_t box)
{
    box->layer->collect0 = 0;
    box->layer->collect_list = (collect_t) 0;
    box->layer->collapse = (collapse_t) 0;
    box->new   = (vca_t) 0;
    box->layer = (fkey_t) 0;
}

/**********************************************************************
 * UNBIND entries
 *   Materialize a variable Y_l target of a renaming during
 *   the collapse pass
 **********************************************************************/

#define TSU( _pos )   ( (_pos)->unbind )

inline static
void TRAIL_UNBIND(fol_t _Y, fkey_t _l, unbind_t *_next)
{
    PUSH_TRAIL_BOX(unbind_t,box);
    box->type  = UNBIND;		
    box->Y     = _Y;		
    box->l     = _l;		
    box->rename_list = (rename_t) 0;
    box->next  = *_next;			
    *_next = box;				
}

/**********************************************************************
 * RENAME entries
 *    Materialize a renamed variable X_k during the collapse pass
 **********************************************************************/

#define TSR( _pos )   ( (_pos)->rename )

inline static
void TRAIL_RENAME(fol_t X, fkey_t k, rename_t *from)
{					
    PUSH_TRAIL_BOX(rename_t,box);		
    box->type  = RENAME;			
    box->X     = X;			
    box->k     = k;			
    box->next  = *from;			
    *from     = box;			
}

/**********************************************************************
 * INDEXATION entries (not yet used)
 *    Materialize a binding done when searching a candidate            
 **********************************************************************/
 
#define TSI( _pos )   ( (_pos)->indexation )

inline static
void TRAIL_INDEXATION(SubsTree _father, SubsTree _son, indexation_t _back)
{
    PUSH_TRAIL_BOX(indexation_t,box);
    box->type   = INDEXATION;
    box->father = _father;
    box->son    = _son;
    box->top    = LSTACK_TOP;
    box->back   = _back;
}

#define UNTRAIL_INDEXATION( _box_ )

/**********************************************************************
 * OVERWRITE entries (not yet used)
 *    Materialize an overwriten layer                                       
 **********************************************************************/

#define TSW( _pos )   ( (_pos)->overwrite )


inline static
void TRAIL_OVERWRITE(fkey_t _key)
{
    PUSH_TRAIL_BOX(overwrite_t,box);	
    box->type = OVERWRITE;			
    box->key  = (_key);			
    box->vca  = (_key)->vca;		
}

inline static
void UNTRAIL_OVERWRITE(overwrite_t box)
{
    box->key->vca = box->vca;		
}

/**********************************************************************
 * COLLECT entries
 *    Materialize a collect list 
 **********************************************************************/

#define TSCL( _pos )   ( (_pos)->collect )

inline static
collect_t TRAIL_COLLECT(unsigned long _index, unsigned long _val, collect_t _next)
{ 					
    PUSH_TRAIL_BOX(collect_t,box);		
    box->type = COLLECT;			
    box->index = _index;			
    box->next = _next;			
    box->collect = _val;			
    return box;				
}

/**********************************************************************
 * ENVIRONEMENT entries
 *    Materialize a new environement (with essentialy a continuation)
 **********************************************************************/

    /* Moved to rt.h */

/**********************************************************************
 * CHOICE entries
 *    Materialize a choice point
 **********************************************************************/

    /* Moved to rt.h */

/**********************************************************************
 * DISPLAY entries
 *    Materialize a display list 
 **********************************************************************/

#define TSDI( _pos )   ( (_pos)->display )

inline static
display_t TRAIL_DISPLAY(fol_t _var, fkey_t _key)
{                                       
    PUSH_TRAIL_BOX(display_t,box);         
    box->type = DISPLAY;                   
    box->var = _var;                       
    box->key = _key;                       
    box->status = 0;
    box->name = (char *) 0;
    box->next = C_TRAIL_DISPLAY;           
    LVALUE_C_TRAIL_DISPLAY = REG_VALUE(box);
    if (_key < R_MIN_LAYER) {
        LVALUE_R_MIN_LAYER=REG_VALUE(_key);
    }
    return box;                                   
}

inline static
void UNTRAIL_DISPLAY(display_t box) 
{
    LVALUE_C_TRAIL_DISPLAY = REG_VALUE(box->next);
}

/**********************************************************************
 * REGISTERS entries
 *    Save additional registers (item-related registers)
 **********************************************************************/

    /* Moved to rt.h */

/**********************************************************************
 * tagging local and layer bindings
 **********************************************************************/

#define LAYER_MASK     1
#define TAG_LAYER_BINDING( b )   ((binding_t) (((unsigned long)b) + LAYER_MASK ))
#define UNTAG_LAYER_BINDING( b ) ((sbind_t) (((unsigned long)b) - LAYER_MASK ))
#define LAYER_BINDING_P( b )     (((unsigned long) b) & LAYER_MASK)

/***********************************************************************
 * The calls to the different dereferencers
 *     (we must be able to modify the input variables)
 ***********************************************************************/

#define ASM_LOAD(X,k)                           \
{                                               \
    LVALUE_REG( I_DEREF_A ) = REG_VALUE(X);             \
    LVALUE_REG( I_DEREF_K ) = REG_VALUE(k);             \
}

#define ASM_UNLOAD(X,k)                         \
{                                               \
    X = (fol_t) REG( I_DEREF_A );               \
    k = (fkey_t) REG( I_DEREF_K );              \
}

#define WRAP_DEREF( __deref, X, k)			\
     ({ binding_t __value = (binding_t) __deref(X,k);	\
        if ((Bool)__value) ASM_UNLOAD(X,k);		\
	__value; })

#define ONCE_U_DEREF( X, k)   WRAP_DEREF( once_u_deref,  X, k )
#define ONCE_S_DEREF( X, k)   WRAP_DEREF( once_s_deref,  X, k )
#define ONCE_L_DEREF( X, k)   WRAP_DEREF( once_l_deref,  X, k )
#define ONCE_UL_DEREF( X, k)  WRAP_DEREF( once_ul_deref, X, k )
#define CLOSURE_UL_DEREF(X,k) WRAP_DEREF( closure_ul_deref, X, k)
#define LOOP_DEREF(X,k)       WRAP_DEREF( loop_deref, X,k )

extern fkey_t load_layer_archive(const unsigned long, obj_t);

#define Collapse_Unwrap( o, k_o, k, env )               \
   ({ obj_t _k_env = collapse(o,k_o);                   \
      k =  NULLP( _k_env ) ? 0 : CINT(CAR( _k_env ));   \
      env     = NULLP( _k_env ) ? BNIL : CDR( _k_env);  \
    })

#endif /* TRAIL_READ */