static void reset_trail(tr_fr_ptr tr_top, tr_fr_ptr trp) { register CELL aux_cell; /* unbinding variables */ while (tr_top != trp) { aux_cell = TrailTerm(--trp); /* check for global or local variables */ if (IsVarTerm(aux_cell)) { /* clean up the trail when we backtrack */ /* shouldn't this test always succeed? */ if (Unsigned((Int)(aux_cell)-(Int)(H_FZ)) > Unsigned((Int)(B_FZ)-(Int)(H_FZ))) { RESET_VARIABLE(STACK_TO_SBA(aux_cell)); } else { RESET_VARIABLE(aux_cell); } } else if (IsPairTerm(aux_cell)) { /* avoid frozen segments */ if ((ADDR) RepPair(aux_cell) > HeapTop) { trp = (tr_fr_ptr) RepPair(aux_cell); } #ifdef MULTI_ASSIGNMENT_VARIABLES } else { CELL *aux_ptr = RepAppl(aux_cell); trp--; if (Unsigned((Int)(aux_ptr)-(Int)(H_FZ)) > Unsigned((Int)(B_FZ)-(Int)(H_FZ))) { *STACK_TO_SBA(aux_ptr) = TrailTerm(trp); } else { *aux_ptr = TrailTerm(trp); } #endif /* MULTI_ASSIGNMENT_VARIABLES */ } } }
static void mark_trail(void) { register tr_fr_ptr pt; pt = TR; /* moving the trail is simple */ while (pt != (tr_fr_ptr)Yap_TrailBase) { CELL reg = TrailTerm(pt-1); if (!IsVarTerm(reg)) { if (IsAtomTerm(reg)) { MarkAtomEntry(RepAtom(AtomOfTerm(reg))); } } pt--; } }
int Yap_Unifiable( Term d0, Term d1 ) { CACHE_REGS tr_fr_ptr trp, trp0 = TR; if (!unifiable(d0,d1)) { return FALSE; } trp = TR; while (trp != trp0) { Term t; --trp; t = TrailTerm(trp); RESET_VARIABLE(t); } return TRUE; }
static Int p_unifiable( USES_REGS1 ) { tr_fr_ptr trp, trp0 = TR; Term tf = TermNil; if (!unifiable(ARG1,ARG2)) { return FALSE; } trp = TR; while (trp != trp0) { Term t[2]; --trp; t[0] = TrailTerm(trp); t[1] = *(CELL *)t[0]; tf = MkPairTerm(Yap_MkApplTerm(FunctorEq,2,t),tf); RESET_VARIABLE(t[0]); } return Yap_unify(ARG3, tf); }
int q_share_work(int worker_p) { register tr_fr_ptr aux_tr; register CELL aux_cell; LOCK_OR_FRAME(LOCAL_top_or_fr); if (REMOTE_prune_request(worker_p)) { /* worker p with prune request */ UNLOCK_OR_FRAME(LOCAL_top_or_fr); return FALSE; } YAPOR_ERROR_CHECKING(q_share_work, Get_OrFr_pend_prune_cp(LOCAL_top_or_fr) && BRANCH_LTT(worker_p, OrFr_depth(LOCAL_top_or_fr)) < OrFr_pend_prune_ltt(LOCAL_top_or_fr)); /* there is no pending prune with worker p at right --> safe move to worker p branch */ CUT_reset_prune_request(); if(Get_LOCAL_prune_request()){ UNLOCK_OR_FRAME(LOCAL_top_or_fr); return FALSE; } BRANCH(worker_id, OrFr_depth(LOCAL_top_or_fr)) = BRANCH(worker_p, OrFr_depth(LOCAL_top_or_fr)); UNLOCK_OR_FRAME(LOCAL_top_or_fr); /* unbind variables */ aux_tr = LOCAL_top_cp->cp_tr; TABLING_ERROR_CHECKING(q_share_work, TR < aux_tr); while (aux_tr != TR) { aux_cell = TrailTerm(--TR); /* check for global or local variables */ if (IsVarTerm(aux_cell)) { RESET_VARIABLE(aux_cell); #ifdef TABLING } else if (IsPairTerm(aux_cell)) { aux_cell = (CELL) RepPair(aux_cell); if (IN_BETWEEN(LOCAL_TrailBase, aux_cell, LOCAL_TrailTop)) { /* avoid frozen segments */ TR = (tr_fr_ptr) aux_cell; TABLING_ERROR_CHECKING(q_share_work, TR > (tr_fr_ptr) LOCAL_TrailTop); TABLING_ERROR_CHECKING(q_share_work, TR < aux_tr); } #endif /* TABLING */ #ifdef MULTI_ASSIGNMENT_VARIABLES } else if (IsApplTerm(aux_cell)) { CELL *aux_ptr = RepAppl(aux_cell); Term aux_val = TrailTerm(--aux_tr); *aux_ptr = aux_val; #endif /* MULTI_ASSIGNMENT_VARIABLES */ } } OPTYAP_ERROR_CHECKING(q_share_work, LOCAL_top_cp != LOCAL_top_cp_on_stack); OPTYAP_ERROR_CHECKING(q_share_work, YOUNGER_CP(B_FZ, LOCAL_top_cp)); YAPOR_ERROR_CHECKING(q_share_work, LOCAL_reply_signal != worker_ready); /* make sharing request */ LOCK_WORKER(worker_p); if (BITMAP_member(GLOBAL_bm_idle_workers, worker_p) || REMOTE_share_request(worker_p) != MAX_WORKERS) { /* worker p is idle or has another request */ UNLOCK_WORKER(worker_p); return FALSE; } REMOTE_share_request(worker_p) = worker_id; UNLOCK_WORKER(worker_p); /* wait for an answer */ while (LOCAL_reply_signal == worker_ready); if (LOCAL_reply_signal == no_sharing) { /* sharing request refused */ LOCAL_reply_signal = worker_ready; return FALSE; } /* copy trail stack ? */ LOCK(LOCAL_lock_signals); if (LOCAL_p_fase_signal > trail) { LOCAL_q_fase_signal = trail; UNLOCK(LOCAL_lock_signals); Q_COPY_TRAIL_FROM(worker_p); } else { UNLOCK(LOCAL_lock_signals); goto sync_with_p; } /* copy global stack ? */ LOCK(LOCAL_lock_signals); if (LOCAL_p_fase_signal > global) { LOCAL_q_fase_signal = global; UNLOCK(LOCAL_lock_signals); Q_COPY_GLOBAL_FROM(worker_p); } else { UNLOCK(LOCAL_lock_signals); goto sync_with_p; } /* copy local stack ? */ while (LOCAL_reply_signal < nodes_shared); LOCK(LOCAL_lock_signals); if (LOCAL_p_fase_signal > local) { LOCAL_q_fase_signal = local; UNLOCK(LOCAL_lock_signals); Q_COPY_LOCAL_FROM(worker_p); } else UNLOCK(LOCAL_lock_signals); sync_with_p: #ifdef TABLING REMOTE_reply_signal(worker_p) = worker_ready; #else REMOTE_reply_signal(worker_p) = copy_done; #endif /* TABLING */ while (LOCAL_reply_signal != copy_done); #if INCREMENTAL_COPY /* install fase --> TR and LOCAL_top_cp->cp_tr are equal */ aux_tr = ((choiceptr) LOCAL_start_local_copy)->cp_tr; TR = ((choiceptr) LOCAL_end_local_copy)->cp_tr; Yap_NEW_MAHASH((ma_h_inner_struct *)HR); while (TR != aux_tr) { aux_cell = TrailTerm(--aux_tr); if (IsVarTerm(aux_cell)) { if (aux_cell < LOCAL_start_global_copy || EQUAL_OR_YOUNGER_CP((choiceptr)LOCAL_end_local_copy, (choiceptr)aux_cell)) { YAPOR_ERROR_CHECKING(q_share_work, (CELL *)aux_cell < H0); YAPOR_ERROR_CHECKING(q_share_work, (ADDR)aux_cell > LOCAL_LocalBase); #ifdef TABLING *((CELL *) aux_cell) = TrailVal(aux_tr); #else *((CELL *) aux_cell) = *((CELL *) (worker_offset(worker_p) + aux_cell)); #endif /* TABLING */ } #ifdef TABLING } else if (IsPairTerm(aux_cell)) { aux_cell = (CELL) RepPair(aux_cell); if (IN_BETWEEN(LOCAL_TrailBase, aux_cell, LOCAL_TrailTop)) { /* avoid frozen segments */ aux_tr = (tr_fr_ptr) aux_cell; } #endif /* TABLING */ #ifdef MULTI_ASSIGNMENT_VARIABLES } else if (IsApplTerm(aux_cell)) { CELL *cell_ptr = RepAppl(aux_cell); if (((CELL *)aux_cell < LOCAL_top_cp->cp_h || EQUAL_OR_YOUNGER_CP(LOCAL_top_cp, (choiceptr)aux_cell)) && !Yap_lookup_ma_var(cell_ptr)) { /* first time we found the variable, let's put the new value */ #ifdef TABLING *cell_ptr = TrailVal(aux_tr); #else *cell_ptr = *((CELL *) (worker_offset(worker_p) + (CELL)cell_ptr)); #endif /* TABLING */ } /* skip the old value */ aux_tr--; #endif /* MULTI_ASSIGNMENT_VARIABLES */ } } #endif /* incremental */ /* update registers and return */ PUT_OUT_ROOT_NODE(worker_id); #ifndef TABLING REMOTE_reply_signal(worker_p) = worker_ready; #endif /* TABLING */ TR = (tr_fr_ptr) LOCAL_end_trail_copy; LOCAL_reply_signal = worker_ready; PUT_IN_REQUESTABLE(worker_id); #ifdef TABLING adjust_freeze_registers(); #endif /* TABLING */ return TRUE; }
static void share_private_nodes(int worker_q) { int depth; choiceptr AuxB; or_fr_ptr or_frame, previous_or_frame; /* initialize auxiliary variables */ AuxB = B; previous_or_frame = NULL; depth = OrFr_depth(LOCAL_top_or_fr); /* sharing loop */ while (AuxB != LOCAL_top_cp) { depth++; ALLOC_OR_FRAME(or_frame); INIT_LOCK(OrFr_lock(or_frame)); OrFr_node(or_frame) = AuxB; OrFr_alternative(or_frame) = AuxB->cp_ap; OrFr_pend_prune_cp(or_frame) = NULL; OrFr_nearest_leftnode(or_frame) = LOCAL_top_or_fr; OrFr_qg_solutions(or_frame) = NULL; BITMAP_clear(OrFr_members(or_frame)); BITMAP_insert(OrFr_members(or_frame), worker_id); BITMAP_insert(OrFr_members(or_frame), worker_q); if (AuxB->cp_ap && YAMOP_SEQ(AuxB->cp_ap)) { AuxB->cp_ap = GETWORK_SEQ; } else { AuxB->cp_ap = GETWORK; } AuxB->cp_or_fr = or_frame; AuxB = AuxB->cp_b; if (previous_or_frame) { OrFr_nearest_livenode(previous_or_frame) = OrFr_next(previous_or_frame) = or_frame; } previous_or_frame = or_frame; } /* initialize last or-frame pointer */ or_frame = AuxB->cp_or_fr; if (previous_or_frame) { OrFr_nearest_livenode(previous_or_frame) = OrFr_next(previous_or_frame) = or_frame; } /* update depth */ if (depth >= MAX_BRANCH_DEPTH) Yap_Error(INTERNAL_ERROR, TermNil, "maximum depth exceded (share_private_nodes)"); or_frame = B->cp_or_fr; while (or_frame != LOCAL_top_or_fr) { unsigned int branch; if (OrFr_alternative(or_frame)) { branch = YAMOP_OR_ARG(OrFr_alternative(or_frame)) + 1; } else { branch = 1; } branch |= YAMOP_CUT_FLAG; /* in doubt, assume cut */ BRANCH(worker_id, depth) = BRANCH(worker_q, depth) = branch; OrFr_depth(or_frame) = depth--; or_frame = OrFr_next_on_stack(or_frame); } /* update old shared nodes */ while (or_frame != REMOTE_top_or_fr(worker_q)) { LOCK_OR_FRAME(or_frame); BRANCH(worker_q, OrFr_depth(or_frame)) = BRANCH(worker_id, OrFr_depth(or_frame)); BITMAP_insert(OrFr_members(or_frame), worker_q); UNLOCK_OR_FRAME(or_frame); or_frame = OrFr_next_on_stack(or_frame); } /* move conditional bindings to BA */ { tr_fr_ptr top, tr_ptr; top = LOCAL_top_cp->cp_tr; tr_ptr = TR; while (tr_ptr != top) { CELL aux_cell = TrailTerm(--tr_ptr); if (IsVarTerm(aux_cell) && ((CELL *)aux_cell < B->cp_h || (choiceptr)aux_cell > B) && !((CELL *)aux_cell < H_FZ || (choiceptr)aux_cell > B_FZ)) { CELL *ptr = STACK_TO_SBA(aux_cell); *ptr = TrailVal(tr_ptr); *(CELL *)aux_cell = (CELL)ptr; } else if (IsPairTerm(aux_cell) && (ADDR) RepPair(aux_cell) > HeapTop) { /* avoid frozen segments */ aux_cell = (CELL) RepPair(aux_cell); tr_ptr = (tr_fr_ptr) aux_cell; #ifdef MULTI_ASSIGNMENT_VARIABLES } else { CELL *cell_ptr = RepAppl(aux_cell); /* first do as a for a standard cell */ if ((cell_ptr < B->cp_h || cell_ptr > (CELL *)B) && !(cell_ptr < H_FZ || (choiceptr)cell_ptr > B_FZ)) { CELL *ptr = STACK_TO_SBA(cell_ptr); /* we may have several bindings in the trail */ if ((CELL)ptr != *cell_ptr) { *ptr = TrailVal(tr_ptr); *cell_ptr = (CELL)ptr; } } /* but we also need to skip the old value */ tr_ptr--; #endif /* MULTI_ASSIGNMENT_VARIABLES */ } } } /* update frozen registers */ B_FZ = B; H_FZ = B->cp_h; TR_FZ = B->cp_tr; /* update top shared nodes */ REMOTE_top_cp(worker_q) = LOCAL_top_cp = B; REMOTE_top_or_fr(worker_q) = LOCAL_top_or_fr = LOCAL_top_cp->cp_or_fr; /* update prune request */ if (LOCAL_prune_request) { CUT_send_prune_request(worker_q, LOCAL_prune_request); } /* update load and return */ REMOTE_load(worker_q) = LOCAL_load = 0; }
int q_share_work(int worker_p) { register tr_fr_ptr aux_tr; register CELL aux_cell; LOCK_OR_FRAME(LOCAL_top_or_fr); if (Get_REMOTE_prune_request(worker_p)) { /* worker p with prune request */ UNLOCK_OR_FRAME(LOCAL_top_or_fr); return FALSE; } YAPOR_ERROR_CHECKING(q_share_work, OrFr_pend_prune_cp(LOCAL_top_or_fr) && BRANCH_LTT(worker_p, OrFr_depth(LOCAL_top_or_fr)) < OrFr_pend_prune_ltt(LOCAL_top_or_fr)); /* there is no pending prune with worker p at right --> safe move to worker p branch */ BRANCH(worker_id, OrFr_depth(LOCAL_top_or_fr)) = BRANCH(worker_p, OrFr_depth(LOCAL_top_or_fr)); LOCAL_prune_request = NULL; UNLOCK_OR_FRAME(LOCAL_top_or_fr); reset_trail(LOCAL_top_cp->cp_tr, TR); TR = LOCAL_top_cp->cp_tr; /* make sharing request */ LOCK_WORKER(worker_p); if (BITMAP_member(GLOBAL_bm_idle_workers, worker_p) || REMOTE_share_request(worker_p) != MAX_WORKERS) { /* worker p is idle or has another request */ UNLOCK_WORKER(worker_p); return FALSE; } REMOTE_share_request(worker_p) = worker_id; UNLOCK_WORKER(worker_p); /* wait for an answer */ while (LOCAL_reply_signal == worker_ready); if (LOCAL_reply_signal == no_sharing) { /* sharing request refused */ LOCAL_reply_signal = worker_ready; return FALSE; } /* install fase --> TR and LOCAL_top_cp->cp_tr are equal */ TR = ((choiceptr)LOCAL_end_local_copy)->cp_tr; aux_tr = ((choiceptr) LOCAL_start_local_copy)->cp_tr; NEW_MAHASH((ma_h_inner_struct *)H); while (TR != aux_tr) { aux_cell = TrailTerm(--aux_tr); if (IsVarTerm(aux_cell)) { CELL *ptr = STACK_TO_SBA(aux_cell); *ptr = TrailVal(aux_tr); } else if ((ADDR) RepPair(aux_cell) >= HeapTop) { /* avoid frozen segments */ aux_tr = (tr_fr_ptr) RepPair(aux_cell); #ifdef MULTI_ASSIGNMENT_VARIABLES } else if (IsApplTerm(aux_cell)) { CELL *cell_ptr = RepAppl(aux_cell); if (!lookup_ma_var(cell_ptr)) { /* first time we found the variable, let's put the new value */ CELL *ptr = STACK_TO_SBA(cell_ptr); *ptr = TrailVal(aux_tr); } /* skip the old value */ aux_tr--; } #endif /* MULTI_ASSIGNMENT_VARIABLES */ } /* update registers and return */ /* REMOTE_reply_signal(worker_p) = worker_ready; */ LOCAL_reply_signal = worker_ready; PUT_IN_REQUESTABLE(worker_id); TR = LOCAL_top_cp->cp_tr; return TRUE; }