/************************************************************************* * * * BEAM -> Basic Extended Andorra Model * * BEAM extends the YAP Prolog system to support the EAM * * * * Copyright: Ricardo Lopes and NCC - University of Porto, Portugal * * * ************************************************************************** * comments: eam compiler data structures and routines * *************************************************************************/ #define Print_Code 0 /* To help on compiler debuging 1 -> show predicates info 2 -> show YAP abstract machine code (YAAM) 4 -> show YAAM after transformation 8 -> show indexing code 16 -> show EAM intermediate code 32 -> show EAM intermediate code with direct_calls 128 -> show EAM abstrac machine code */ #define Variavel 1 #define Lista 2 #define Estrutura 4 #define Constante 8 typedef unsigned long Cell; typedef struct PCODE{ struct PCODE *nextInst; int op, new1; unsigned long new4; } CInstr; struct Clauses { unsigned int idx; /* info for indexing on first arg */ Cell val; /* atom or functor in first arg */ unsigned int nr_vars; /* nr of local vars */ struct Predicates *predi; /* predicate struct */ int side_effects; /* clause has side effects */ Cell *code; struct Clauses *next; /* next clause within the same predicate */ }; struct HASH_TABLE { Cell value; Cell *code; struct HASH_TABLE *next; }; struct Predicates { /* To register information about predicates */ unsigned long id; unsigned char *name; unsigned int arity; unsigned int nr_alt; /* nr of alternativas */ unsigned int calls; /* nr of existent calls to this predicate */ struct Clauses *first; struct Clauses *last; int idx; /* is code indexed ? 0= needs compilation -1= no indexing possible 1= indexed */ unsigned int idx_var; /* nr clauses with 1st argument var */ unsigned int idx_list; /* nr clauses with 1st argument list */ unsigned int idx_atom; /* nr clauses with 1st argument atom */ unsigned int idx_functor; /* nr clauses with 1st argument functor */ short int eager_split; /* allow eager splitting */ Cell *code; /* try, retry and trust code or Indexing code */ struct HASH_TABLE **atom; struct HASH_TABLE **functor; Cell *list; Cell *vars; struct Predicates *next; }; /**************************** EAM TRUE STUFF *************/ struct SUSPENSIONS { struct AND_BOX *and_box; /* And_box where the variable has suspended */ short int reason; /* suspended before executing call number nr_call */ struct SUSPENSIONS *next; /* Pointer to the next suspention */ struct SUSPENSIONS *prev; }; struct SUSPENSIONS_VAR { struct AND_BOX *and_box; /* And_box where the variable has suspended */ struct SUSPENSIONS_VAR *next; /* Pointer to the next suspention */ }; struct PERM_VAR { Cell value; /* value assigned to the variable */ struct AND_BOX *home; /* pointer to the goal_box structure of the variable */ Cell *yapvar; struct SUSPENSIONS_VAR *suspensions; /* Pointer to a Suspension List */ struct PERM_VAR *next; }; struct EXTERNAL_VAR { /* to be used as some kind of trail */ Cell value; /* value assign to the variable */ struct PERM_VAR *var; /* pointer to the local_var struct */ struct EXTERNAL_VAR *next; }; struct status_and { struct OR_BOX *call; /* POINTER TO A OR_BOX */ Cell *locals; /* temporary vars vector */ Cell *code; /* Pointer to the start code */ int state; /* State of the OR_BOX */ struct status_and *previous; struct status_and *next; }; struct status_or { struct AND_BOX *alternative; /* POINTER TO A AND_BOX */ Cell *args; /* Saved Arguments */ Cell *code; /* Pointer to Start Code */ int state; /* State of the AND_BOX */ struct status_or *previous; struct status_or *next; }; struct OR_BOX { struct AND_BOX *parent; struct status_and *nr_call; /* order of this box */ short int nr_all_alternatives; /* number of existing alternatives */ struct status_or *alternatives; /* alternatives of the or_box */ short int eager_split; }; struct AND_BOX { struct OR_BOX *parent; /* pointer to the parent or-box */ struct status_or *nr_alternative; /* This box is alternative id */ short int nr_all_calls; /* numger of all goals */ struct PERM_VAR *perms; struct status_and *calls; short int level; /* indicates the level in the tree */ struct EXTERNAL_VAR *externals; /* pointer to a list of external_vars */ struct SUSPENSIONS *suspended; /* pointer to a list of suspended boxes */ short int side_effects; /* to mark if are calls to builtins with side_efects (like write) */ }; /* TYPE OF STATES */ #define ZERO 0 /* No State yet */ #define SUCCESS 1 #define FAILS 2 #define READY 4 /* Is ready to start execution */ #define RUNNING 8 /* Is running */ #define RUNAGAIN 16 /* Is running again */ #define SUSPEND 32 /* Has suspended */ #define WAKE 64 /* Was Suspended, but now is Ready again */ #define CHANGED 128 /* Has received some change on it's external variables, needs to re-run */ #define END 256 /* Has suspended on end, on wake up can pass to a success state */ #define WAITING 512 /* The clause is waiting for the previous predicates to leave the Suspended state */ #define FAILED 1024 /* has failed */ #define CUT_RIGHT 2048 #define SKIP_VAR 4096 #define LEFTMOST_PARENT 8192 #define FIRST 16384 #define LEFTMOST 32768 #define WAITING_TO_BE_FIRST (WAITING + FIRST) #define WAITING_TO_BE_LEFTMOST (WAITING + LEFTMOST) #define WAITING_TO_BE_LEFTMOST_PARENT (WAITING + LEFTMOST_PARENT) #define WAITING_TO_CUT (WAITING + CUT_RIGHT) #define WAITING_SKIP_VAR (WAITING + SKIP_VAR) #define SUSPEND_END (SUSPEND+END) #define WAKE_END (WAKE+END) #define NORMAL_SUSPENSION 0 #define LEFTMOST_SUSPENSION 1 #define WAIT_SUSPENSION 2 #define CUT_SUSPENSION 3 #define WRITE_SUSPENSION 4 #define VAR_SUSPENSION 5 #define YAP_VAR_SUSPENSION 6 /* TYPE OF SIDE_EFFECTS */ #define WRITE 1 #define COMMIT 2 #define VAR 4 #define SEQUENCIAL 8 #define CUT 32 /* Greater than 32 always cut */ /**********************************************************************************/ struct EAM_TEMP { struct EAM_TEMP *previous; struct EAM_TEMP *next; }; struct EAM_Global { Cell *pc; Cell *_H; Cell *_S; short _Mode; /* read or write mode */ short ES; /* goal shoud do Eager Split yes or no ? */ short MemGoing; /* Direction the that stacks use to grow */ Cell *varlocals; /* local vars to the working AND-BOX */ struct AND_BOX *ABX; /* working AND-BOX */ struct OR_BOX *OBX; /* working OR-BOX */ struct SUSPENSIONS *su; /* list with suspended work */ struct AND_BOX *top; struct status_and *USE_SAME_ANDBOX; /* when only 1 alternative */ struct status_or *nr_alternative; /* working alternative */ struct status_and *nr_call; /* working goal */ Cell *VAR_TRAIL; int VAR_TRAIL_NR; int Mem_FULL; /* if mem_full, then perform GC */ int nr_call_forking; /* number of splits already performed */ unsigned long START_ADDR_HEAP, START_ADDR_BOXES, END_BOX, END_H; unsigned int nr_gc_heap; unsigned int nr_gc_boxed; Cell **IndexFree; Cell *NextFree; Cell *sp; struct PERM_VAR *NextVar; #if Memory_Stat unsigned long TOTAL_MEM, MEM_REUSED, TOTAL_TEMPS,TEMPS_REUSED, TOTAL_PERMS, PERMS_REUSED; unsigned long Memory_STAT[5000][5]; #endif }; #define beam_X XREGS /* use the same X-Regs as YAP */ #define beam_pc (eamGlobal->pc) #define beam_H (eamGlobal->_H) #define beam_S (eamGlobal->_S) #define beam_Mode (eamGlobal->_Mode) #define beam_ES (eamGlobal->ES) #define beam_MemGoing (eamGlobal->MemGoing) #define beam_varlocals (eamGlobal->varlocals) #define beam_ABX (eamGlobal->ABX) #define beam_OBX (eamGlobal->OBX) #define beam_su (eamGlobal->su) #define beam_top (eamGlobal->top) #define beam_USE_SAME_ANDBOX (eamGlobal->USE_SAME_ANDBOX) #define beam_nr_alternative (eamGlobal->nr_alternative) #define beam_nr_call (eamGlobal->nr_call) #define beam_VAR_TRAIL (eamGlobal->VAR_TRAIL) #define beam_VAR_TRAIL_NR (eamGlobal->VAR_TRAIL_NR) #define beam_Mem_FULL (eamGlobal->Mem_FULL) #define beam_nr_call_forking (eamGlobal->nr_call_forking) #define beam_START_ADDR_HEAP (eamGlobal->START_ADDR_HEAP) #define beam_START_ADDR_BOXES (eamGlobal->START_ADDR_BOXES) #define beam_END_BOX (eamGlobal->END_BOX) #define beam_END_H (eamGlobal->END_H) #define beam_nr_gc_heap (eamGlobal->nr_gc_heap) #define beam_nr_gc_boxed (eamGlobal->nr_gc_boxed) #define beam_IndexFree (eamGlobal->IndexFree) #define beam_NextFree (eamGlobal->NextFree) #define beam_sp (eamGlobal->sp) #define beam_NextVar (eamGlobal->NextVar) #if Memory_Stat #define beam_TOTAL_MEM (eamGlobal->TOTAL_MEM) #define beam_MEM_REUSED (eamGlobal->MEM_REUSED) #define beam_TOTAL_TEMPS (eamGlobal->TOTAL_TEMPS) #define beam_TEMPS_REUSED (eamGlobal->TEMPS_REUSED) #define beam_TOTAL_PERMS (eamGlobal->TOTAL_PERMS) #define beam_PERMS_REUSED (eamGlobal->PERMS_REUSED) #define beam_Memory_STAT (eamGlobal->Memory_STAT) #endif #define arg1 *(beam_pc+1) #define arg2 *(beam_pc+2) #define arg3 *(beam_pc+3) #define arg4 *(beam_pc+4) #define CELL_SIZE (sizeof(Cell)) #define POINTER_SIZE (sizeof(Cell *)) #define ANDBOX_SIZE (sizeof(struct AND_BOX)) #define ORBOX_SIZE (sizeof(struct OR_BOX)) #define PERM_VAR_SIZE (sizeof(struct PERM_VAR)) #define EXTERNAL_VAR_SIZE (sizeof(struct EXTERNAL_VAR)) #define SUSPENSIONS_SIZE (sizeof(struct SUSPENSIONS)) #define SUSPENSIONS_VAR_SIZE (sizeof(struct SUSPENSIONS_VAR)) #define STATUS_AND_SIZE (sizeof(struct status_and)) #define STATUS_OR_SIZE (sizeof(struct status_or))