/************************************************************************* * * * YAP Prolog %W% %G% * * * * Yap Prolog was developed at NCCUP - Universidade do Porto * * * * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 * * * ************************************************************************** * * * File: clause.h * * Last rev: * * mods: * * comments: clause info * * * *************************************************************************/ #include "Yatom.h" #include "YapHeap.h" /* consulting files */ typedef union CONSULT_OBJ { char *filename; int mode; Prop p; UInt c; } consult_obj; /* Either we are assembling clauses or indexing code */ #define ASSEMBLING_CLAUSE 0 #define ASSEMBLING_INDEX 1 #define ASSEMBLING_EINDEX 2 #define NextDynamicClause(X) (((yamop *)X)->u.Otapl.d) #define PredFirstClause 0 #define PredMiddleClause 1 #define PredLastClause 2 typedef struct logic_upd_index { CELL ClFlags; UInt ClRefCount; #if defined(YAPOR) || defined(THREADS) /* A lock for manipulating the clause */ // lockvar ClLock; #endif UInt ClSize; struct logic_upd_index *ParentIndex; struct logic_upd_index *SiblingIndex; struct logic_upd_index *PrevSiblingIndex; struct logic_upd_index *ChildIndex; /* The instructions, at least one of the form sl */ PredEntry *ClPred; yamop ClCode[MIN_ARRAY]; } LogUpdIndex; /* The ordering of the first 3 fields should be compatible with dbrefs */ typedef struct logic_upd_clause { Functor Id; /* allow pointers to this struct to id */ /* as dbref */ /* A set of flags describing info on the clause */ /* A set of flags describing info on the clause */ CELL ClFlags; #if defined(YAPOR) || defined(THREADS) /* A lock for manipulating the clause */ // lockvar ClLock; #endif UInt ClSize; /* extra clause information for logical update indices and facts */ /* indices that may still backtrack to this clause */ UInt ClRefCount; /* data for clauses with environments */ yamop *ClExt; union { DBTerm *ClSource; Int ClLine; } lusl; /* doubly linked list of clauses */ struct logic_upd_clause *ClPrev, *ClNext; /* parent pointer */ PredEntry *ClPred; UInt ClTimeStart, ClTimeEnd; /* The instructions, at least one of the form sl */ yamop ClCode[MIN_ARRAY]; } LogUpdClause; #include "inline-only.h" INLINE_ONLY inline EXTERN int VALID_TIMESTAMP(UInt, struct logic_upd_clause *); INLINE_ONLY inline EXTERN int VALID_TIMESTAMP(UInt timestamp, struct logic_upd_clause *cl) { return IN_BETWEEN(cl->ClTimeStart, timestamp, cl->ClTimeEnd); } typedef struct dynamic_clause { /* A set of flags describing info on the clause */ CELL ClFlags; #if defined(YAPOR) || defined(THREADS) /* A lock for manipulating the clause */ lockvar ClLock; #endif UInt ClSize; Int ClLine; UInt ClRefCount; yamop *ClPrevious; /* immediate update clause */ /* The instructions, at least one of the form sl */ yamop ClCode[MIN_ARRAY]; } DynamicClause; typedef struct static_index { /* A set of flags describing info on the clause */ CELL ClFlags; UInt ClSize; struct static_index *SiblingIndex; struct static_index *ChildIndex; /* The instructions, at least one of the form sl */ PredEntry *ClPred; yamop ClCode[MIN_ARRAY]; } StaticIndex; typedef struct static_clause { /* A set of flags describing info on the clause */ CELL ClFlags; UInt ClSize; union { DBTerm *ClSource; Int ClLine; } usc; struct static_clause *ClNext; /* The instructions, at least one of the form sl */ yamop ClCode[MIN_ARRAY]; } StaticClause; typedef struct static_mega_clause { /* A set of flags describing info on the clause */ CELL ClFlags; UInt ClSize; PredEntry *ClPred; UInt ClItemSize; Int ClLine; struct static_mega_clause *ClNext; /* The instructions, at least one of the form sl */ yamop ClCode[MIN_ARRAY]; } MegaClause; typedef union clause_obj { struct logic_upd_clause luc; struct logic_upd_index lui; struct dynamic_clause ic; struct static_clause sc; struct static_mega_clause mc; struct static_index si; } ClauseUnion; typedef union clause_ptr { struct logic_upd_clause *luc; struct logic_upd_index *lui; struct dynamic_clause *ic; struct static_clause *sc; struct static_mega_clause *mc; struct static_index *si; } ClausePointer; typedef struct index_t { struct index_t *next, *prev; UInt nels; UInt arity; PredEntry *ap; CELL bmap; int is_key; int is_udi; UInt ncollisions; UInt max_col_count; UInt ntrys; UInt nentries; UInt hsize; BITS32 *key; CELL *cls, *bcls; BITS32 *links; size_t size; yamop *code; BITS32 *udi_data; void *udi_first, *udi_next; UInt udi_free_args; UInt udi_arg; } Index_t; INLINE_ONLY EXTERN inline BITS32 EXO_ADDRESS_TO_OFFSET(struct index_t *it, CELL *ptr); INLINE_ONLY EXTERN inline BITS32 EXO_ADDRESS_TO_OFFSET(struct index_t *it, CELL* ptr) { return (ptr-it->cls)/it->arity+1; } INLINE_ONLY EXTERN inline CELL *EXO_OFFSET_TO_ADDRESS(struct index_t *it, BITS32 off); INLINE_ONLY EXTERN inline CELL * EXO_OFFSET_TO_ADDRESS(struct index_t *it, BITS32 off) { if (off == 0L) return NULL; return (it->cls)+(off-1)*it->arity; } INLINE_ONLY EXTERN inline BITS32 ADDRESS_TO_LINK(struct index_t *it, BITS32 *ptr); INLINE_ONLY EXTERN inline BITS32 ADDRESS_TO_LINK(struct index_t *it, BITS32* ptr) { return ptr-it->links; } INLINE_ONLY EXTERN inline BITS32 *LINK_TO_ADDRESS(struct index_t *it, BITS32 off); INLINE_ONLY EXTERN inline BITS32 * LINK_TO_ADDRESS(struct index_t *it, BITS32 off) { return it->links+off; } typedef void (*CRefitExoIndex)(struct index_t **ip, UInt b[] USES_REGS); typedef yamop * (*CEnterExoIndex)(struct index_t *it USES_REGS); typedef int (*CRetryExoIndex)(struct index_t *it USES_REGS); typedef struct dbterm_list { /* a list of dbterms associated with a clause */ DBTerm *dbterms; yamop *clause_code; PredEntry *p; struct dbterm_list *next_dbl; } DBTermList; #define ClauseCodeToDynamicClause(p) ((DynamicClause *)((CODEADDR)(p)-(CELL)(((DynamicClause *)NULL)->ClCode))) #define ClauseCodeToStaticClause(p) ((StaticClause *)((CODEADDR)(p)-(CELL)(((StaticClause *)NULL)->ClCode))) #define ClauseCodeToLogUpdClause(p) ((LogUpdClause *)((CODEADDR)(p)-(CELL)(((LogUpdClause *)NULL)->ClCode))) #define ClauseCodeToMegaClause(p) ((MegaClause *)((CODEADDR)(p)-(CELL)(((MegaClause *)NULL)->ClCode))) #define ClauseCodeToLogUpdIndex(p) ((LogUpdIndex *)((CODEADDR)(p)-(CELL)(((LogUpdIndex *)NULL)->ClCode))) #define ClauseCodeToStaticIndex(p) ((StaticIndex *)((CODEADDR)(p)-(CELL)(((StaticIndex *)NULL)->ClCode))) #define ClauseFlagsToDynamicClause(p) ((DynamicClause *)(p)) #define ClauseFlagsToLogUpdClause(p) ((LogUpdClause *)((CODEADDR)(p)-(CELL)(&(((LogUpdClause *)NULL)->ClFlags)))) #define ClauseFlagsToLogUpdIndex(p) ((LogUpdIndex *)((CODEADDR)(p)-(CELL)(&(((LogUpdIndex *)NULL)->ClFlags)))) #define ClauseFlagsToStaticClause(p) ((StaticClause *)(p)) #define DynamicFlags(X) (ClauseCodeToDynamicClause(X)->ClFlags) #define DynamicLock(X) (ClauseCodeToDynamicClause(X)->ClLock) #if MULTIPLE_STACKS #define INIT_CLREF_COUNT(X) (X)->ClRefCount = 0 #define INC_CLREF_COUNT(X) (X)->ClRefCount++ #define DEC_CLREF_COUNT(X) (X)->ClRefCount-- #define CL_IN_USE(X) ((X)->ClRefCount) #else #define INIT_CLREF_COUNT(X) #define INC_CLREF_COUNT(X) #define DEC_CLREF_COUNT(X) #define CL_IN_USE(X) ((X)->ClFlags & InUseMask || (X)->ClRefCount) #endif /* amasm.c */ wamreg Yap_emit_x(CELL); COUNT Yap_compile_cmp_flags(PredEntry *); void Yap_InitComma(void); /* cdmgr.c */ void Yap_IPred(PredEntry *, UInt, yamop *); int Yap_addclause(Term,yamop *,int,Term,Term*); void Yap_add_logupd_clause(PredEntry *,LogUpdClause *,int); void Yap_kill_iblock(ClauseUnion *,ClauseUnion *,PredEntry *); void Yap_EraseStaticClause(StaticClause *, PredEntry *, Term); ClauseUnion *Yap_find_owner_index(yamop *, PredEntry *); /* dbase.c */ void Yap_ErCl(DynamicClause *); void Yap_ErLogUpdCl(LogUpdClause *); void Yap_ErLogUpdIndex(LogUpdIndex *); Int Yap_Recordz(Atom, Term); Int Yap_db_nth_recorded( PredEntry *, Int USES_REGS ); Int Yap_unify_immediate_ref(DBRef ref USES_REGS ); /* exec.c */ Term Yap_cp_as_integer(choiceptr); /* index.c */ yamop *Yap_PredIsIndexable(PredEntry *, UInt, yamop *); yamop *Yap_ExpandIndex(PredEntry *, UInt); void Yap_CleanUpIndex(struct logic_upd_index *); void Yap_CleanKids(struct logic_upd_index *); void Yap_AddClauseToIndex(PredEntry *,yamop *,int); void Yap_RemoveClauseFromIndex(PredEntry *,yamop *); LogUpdClause *Yap_NthClause(PredEntry *,Int); LogUpdClause *Yap_FollowIndexingCode(PredEntry *,yamop *, Term *, yamop *,yamop *); /* exo.c */ yamop *Yap_ExoLookup(PredEntry *ap USES_REGS); CELL Yap_NextExo(choiceptr cpt, struct index_t *it); #if USE_THREADED_CODE #define OP_HASH_SIZE 2048 static inline int rtable_hash_op(OPCODE opc, int hash_mask) { return((((CELL)opc) >> 3) & hash_mask); } /* given an opcode find the corresponding opnumber. This should make switches on ops a much easier operation */ static inline op_numbers Yap_op_from_opcode(OPCODE opc) { int j = rtable_hash_op(opc,OP_HASH_SIZE-1); while (OP_RTABLE[j].opc != opc) { if (!OP_RTABLE[j].opc) return _Nstop; if (j == OP_HASH_SIZE-1) { j = 0; } else { j++; } } return OP_RTABLE[j].opnum; } #else static inline op_numbers Yap_op_from_opcode(OPCODE opc) { return((op_numbers)opc); } #endif /* USE_THREADED_CODE */ #if defined(YAPOR) || defined(THREADS) static inline int same_lu_block(yamop **, yamop *); static inline int same_lu_block(yamop **paddr, yamop *p) { yamop *np = *paddr; if (np != p) { OPCODE jmp_op = Yap_opcode(_jump_if_nonvar); while (np->opc == jmp_op) { np = NEXTOP(np, xll); if (np == p) return TRUE; } return FALSE; } else { return TRUE; } } #endif #define Yap_MkStaticRefTerm(cp, ap) __Yap_MkStaticRefTerm((cp), (ap) PASS_REGS) static inline Term __Yap_MkStaticRefTerm(StaticClause *cp, PredEntry *ap USES_REGS) { Term t[2]; t[0] = MkIntegerTerm((Int)cp); t[1] = MkIntegerTerm((Int)ap); return Yap_MkApplTerm(FunctorStaticClause,2,t); } static inline StaticClause * Yap_ClauseFromTerm(Term t) { return (StaticClause *)IntegerOfTerm(ArgOfTerm(1,t)); } #define Yap_MkMegaRefTerm(ap, ipc) __Yap_MkMegaRefTerm((ap), (ipc) PASS_REGS) static inline Term __Yap_MkMegaRefTerm(PredEntry *ap,yamop *ipc USES_REGS) { Term t[2]; t[0] = MkIntegerTerm((Int)ap); t[1] = MkIntegerTerm((Int)ipc); return Yap_MkApplTerm(FunctorMegaClause,2,t); } static inline yamop * Yap_MegaClauseFromTerm(Term t) { return (yamop *)IntegerOfTerm(ArgOfTerm(2,t)); } static inline PredEntry * Yap_MegaClausePredicateFromTerm(Term t) { return (PredEntry *)IntegerOfTerm(ArgOfTerm(1,t)); } #define Yap_MkExoRefTerm(ap, i) __Yap_MkExoRefTerm((ap), (i) PASS_REGS) static inline Term __Yap_MkExoRefTerm(PredEntry *ap,Int i USES_REGS) { Term t[2]; t[0] = MkIntegerTerm((Int)ap); t[1] = MkIntegerTerm((Int)i); return Yap_MkApplTerm(FunctorExoClause,2,t); } static inline Int Yap_ExoClauseFromTerm(Term t) { return IntegerOfTerm(ArgOfTerm(2,t)); } static inline PredEntry * Yap_ExoClausePredicateFromTerm(Term t) { return (PredEntry *)IntegerOfTerm(ArgOfTerm(1,t)); } #define DEAD_REF(ref) FALSE typedef enum { FIND_PRED_FROM_ANYWHERE, FIND_PRED_FROM_CP, FIND_PRED_FROM_ENV } find_pred_type; Int Yap_PredForCode(yamop *, find_pred_type, Atom *, UInt *, Term *); PredEntry *Yap_PredEntryForCode(yamop *, find_pred_type, CODEADDR *, CODEADDR *); LogUpdClause *Yap_new_ludbe(Term, PredEntry *, UInt); Term Yap_LUInstance(LogUpdClause *, UInt); /* udi.c */ int Yap_new_udi_clause(PredEntry *, yamop *, Term); yamop *Yap_udi_search(PredEntry *); #ifdef DEBUG void Yap_bug_location(yamop *); #endif #if LOW_PROF void Yap_InformOfRemoval(void *); void Yap_dump_code_area_for_profiler(void); #else #define Yap_InformOfRemoval(X) #endif