int PVS(int alpha, int beta, int depth) { if(is_draw_by_repetition_or_50_moves()) return DRAW; if(depth == 0) return quiescence(alpha, beta); Move movelist[256]; int n = generate_moves(movelist); if(n == 0) { if(!in_check(turn_to_move)) return DRAW; return LOSING + ply - begin_ply; } sorting_moves(movelist, n); int bool_search_pv = 1; Move bestmove = 0; for(int i = 0; i < n; i += 1) { Move i_move = movelist[i]; make_move(i_move); int score; if(bool_search_pv) { score = -PVS(-beta, -alpha, depth - 1); } else { score = -ZWS(-alpha, depth - 1, 1); if(score > alpha) score = -PVS(-beta, -alpha, depth - 1); } unmake_move(i_move); if(score >= beta) { hash_save_entry(depth, beta, i_move, MORE_THAN_BETA); if(!move_broken(i_move)) { history[board[move_from(i_move)]][move_to(i_move)] = depth * depth; } return beta; } if(score > alpha) { bestmove = i_move; alpha = score; } bool_search_pv = 0; } if(bestmove != 0) hash_save_entry(depth, alpha, bestmove, BETWEEN_ALPHA_AND_BETA); else hash_save_entry(depth, alpha, 0, LESS_THAN_ALPHA); return alpha; }
Move search(int depth) { PVS(-1000000, 1000000, depth); Entry *entry = hash_get_entry(); if(entry != NULL) return entry->bestmove; return 0; }
int Eval(const uint64_t P, const uint64_t O, uint64_t& NodeCounter, const int alpha, const int beta, const int selectivity, int depth, const int empties, CLine* pline) { assert((P & O) == 0); assert(-64 <= alpha); assert(alpha <= 64); assert(-64 <= beta ); assert(beta <= 64); assert(alpha <= beta); assert(0 <= depth); assert(depth <= 60); assert(0 <= empties); assert(empties <= 60); assert(empties == Empties(P, O)); assert(depth <= empties); return PVS(P, O, NodeCounter, alpha, beta, selectivity, depth, empties, pline); }
static const char* type_system_v1_docstring(type_system_v1::closure_t* self, type_system_v1::alias tc) { D(kconsole << "type_system.docstring" << endl); interface_v1::state_t* iface = nullptr; /* Check the type code refers to a valid interface */ if (!reinterpret_cast<type_system_f_v1::state_t*>(self->d_state)->interfaces_by_typecode->get(TCODE_INTF_CODE(tc), (address_t*)&iface)) OS_RAISE((exception_support_v1::id)"type_system_v1.bad_code", tc); /* Deal with the case where the type code refers to an interface type */ if (TCODE_IS_INTERFACE(tc)) { return string_copy(iface->rep.autodoc, PVS(heap)); } /* Check that within the given interface this is a valid type */ if (!TCODE_VALID_TYPE (tc, iface)) OS_RAISE((exception_support_v1::id)"type_system_v1.bad_code", tc); type_representation_t* trep = TCODE_WHICH_TYPE(tc, iface); return string_copy(trep->autodoc, PVS(heap)); }
/** * Return a list of all types in the type system. */ static naming_context_v1::names type_system_v1_list(naming_context_v1::closure_t* self) { auto state = reinterpret_cast<type_system_f_v1::closure_t*>(self)->d_state; naming_context_v1::names n; map_string_address_iterator_v1::closure_t* it = nullptr; /* Run through all the interfaces */ OS_TRY { const char* name; interface_v1::state_t* tb; type_representation_t* trep; it = state->interfaces_by_name->iterate(); while (it->next(&name, (memory_v1::address*)&tb)) { add_name(tb->rep.name, PVS(heap), n); /* Run through all the types defined in the current interface */ for (size_t i = 0; i < tb->num_types; ++i) { trep = tb->types[i]; add_qual_name(tb->rep.name, trep->name, PVS(heap), n); } } it->dispose(); } OS_CATCH_ALL { if (it) it->dispose(); OS_RAISE((exception_support_v1::id)"heap_v1.no_memory", 0); } OS_ENDTRY; return n; }
static void events_destroy(events_v1::closure_t* self, event_v1::count ec) { instance_state_t* istate = self->d_state->inst_state; event_count_t* event_count = reinterpret_cast<event_count_t*>(ec); vcpu_lock_t lock(istate->vcpu); unblock_event(istate, event_count, /*alerted:*/true); // Alert all waiters on this event count. event_count->ec_queue.remove(); if (event_count->ep != NULL_EP) { if (event_count->prev_notify) event_count->prev_notify->set_link(chained_handler_v1::position_after, reinterpret_cast<chained_handler_v1::closure_t*>(event_count->next_notify));// oh, man. else { // We were the head of the notify queue, so attach the old handler (may be NULL) to the endpoint. istate->dispatcher->attach(event_count->next_notify, event_count->ep); } if (event_count->next_notify) event_count->next_notify->set_link(chained_handler_v1::position_before, reinterpret_cast<chained_handler_v1::closure_t*>(event_count->prev_notify));// oh, man. } lock.unlock(); // The closedown call to the binder must be outside the critical section: it does a blocking IDC call. if (event_count->ep != NULL_EP) { PVS(binder)->close(event_count->ep); self->destroy_channel(event_count->ep); } // Finally, we can free the event count. lock.lock(); istate->heap->free(reinterpret_cast<memory_v1::address>(event_count)); // oh, man. }
/** * Look up a type name in this interface. */ static type_representation_t* internal_get(type_system_f_v1::state_t* state, const char* name) { interface_v1::state_t* iface = nullptr; type_representation_t* result = nullptr; stringref_t name_sr(name); std::pair<stringref_t, stringref_t> refs = name_sr.split('.'); // @todo: move this allocation to stringref_t guts? if (!refs.second.empty()) name = string_n_copy(refs.first.data(), refs.first.size(), PVS(heap)); // @todo MEMLEAK /* now "name" is just the interface, and "extra" is any extra qualifier */ if (state->interfaces_by_name->get(name, (address_t*)&iface)) { /* We've found the first component. */ if (!refs.second.empty()) { for (int i = 0; iface->types[i]; ++i) if (refs.second == iface->types[i]->name) result = iface->types[i]; /* special case if it's an intf type defined by the metainterface */ if (!result && (iface == &meta_interface)) { result = internal_get(state, refs.second.data()); // this should trigger search in "meta_interface.<something>" but that won't work atm } } else { /* Otherwise return this interface clp */ result = &iface->rep; } } return result; }
CMoveList::CMoveList(uint64_t P, uint64_t O, uint64_t& NodeCounter, uint64_t BitBoardPossible, int depth, int alpha, const CHashTableValueType& ttValue, const bool pvs) { //if (!pvs) depth -= 2; static const int A = 9; static const int C = 8; static const int H = 7; static const int D = 6; static const int I = 5; static const int G = 4; static const int F = 3; static const int B = 2; static const int E = 1; static const int J = 0; static const int FIELD_VALUE[64] = { A, B, C, D, D, C, B, A, B, E, F, G, G, F, E, B, C, F, H, I, I, H, F, C, D, G, I, J, J, I, G, D, D, G, I, J, J, I, G, D, C, F, H, I, I, H, F, C, B, E, F, G, G, F, E, B, A, B, C, D, D, C, B, A, }; static const int PARITY_VALUE[16] = { 0, 20, 0, 10, 1, 10, 2, 10, 3, 5, 3, 4, 3, 4, 3, 4 }; const uint64_t BBEmpties = ~(P | O); const uint64_t empties = Empties(P, O); m_Moves = std::vector<CMove>(PopCount(BitBoardPossible)); int index = 0; int sort_depth; int min_depth = 9; if (empties <= 27) min_depth += (30 - empties) / 3; if (depth >= min_depth) { sort_depth = (depth - 15) / 3; if (ttValue.beta < alpha) sort_depth -= 2; sort_depth = BIND(sort_depth, 0, 6); } else sort_depth = -1; int sort_alpha = MAX(-64, alpha - 8); // Fill MoveList while (BitBoardPossible) { CMove Move; Move.move = BitScanLSB(BitBoardPossible); RemoveLSB(BitBoardPossible); uint64_t flipped = flip(P, O, Move.move); Move.P = O ^ flipped; Move.O = P ^ flipped ^ (1ULL << Move.move); if (flipped == O) Move.Value = 1 << 31; else if ((ttValue.depth > sort_depth) && (Move.move == ttValue.PV)) Move.Value = 1 << 30; else if ((ttValue.depth > sort_depth) && (Move.move == ttValue.AV)) Move.Value = 1 << 29; else { uint64_t PossMoves = PossibleMoves(Move.P, Move.O); Move.Value = FIELD_VALUE[Move.move]; Move.Value += PARITY_VALUE[PopCount(BBEmpties & quadrant_mask[Move.move])]; Move.Value -= PopCount(PossMoves) << 17; Move.Value -= PopCount(PossMoves & 0x8100000000000081UL) << 18; if (sort_depth < 0) Move.Value += PopCount(StableStonesCornerAndCo(Move.O)) << 12; else Move.Value += PopCount(StableEdges(Move.O, Move.P) & Move.O) << 12; Move.Value -= PopCount(OpponentsExposed(Move.P, Move.O)) << 6; switch (sort_depth) { case -1: break; case 0: Move.Value -= EvaluateFeatures(Move.P, Move.O) << 16; break; case 1: case 2: Move.Value -= PVS(Move.P, Move.O, NodeCounter, -64, -sort_alpha, NO_SELECTIVITY, sort_depth, empties-1) << 17; break; default: Move.Value -= PVS(Move.P, Move.O, NodeCounter, -64, -sort_alpha, NO_SELECTIVITY, sort_depth, empties-1) << 18; CHashTableValueType ttValue2; if (TT.LookUp(Move.P, Move.O, ttValue2)) Move.Value += 1 << 21; break; } } m_Moves[index++] = Move; } sort(); return; }
float ScopeDome::getDewPoint(float RH, float T) { T = T + C_OFFSET; return solve(PVS, RH / 100 * PVS(T), T) - C_OFFSET; }
void CPartida::IterativeDeepening(void) { extern void Print(const char *fmt, ...); long ini_it; int value,value_i; int hasp; int MateCount = 0; // busqueda con ventana int VAlpha,VBeta,Pase; int Valor_d1; char JugD1[20]; ValueSearch = 0; NodosVisitados = 0; cancelado = 0; NodosRepasados = 0; SelDepth = 0; inicio = TiempoTranscurrido(); // copiamos tablero principal Taux.LoadEPD(T.SaveEPD(),0); ResetHistory(); char PV[1024]; PV[0] = '\0'; value = -INFINITO; T.CalculaJugadasPosibles(); HashJ.IncrementaEdad(); JugadaActual[0] = '\0'; strcpy(JugadaActual,T.JugadasPosibles[0].ToString()); Depth = 1; value_i = value = PVS(Depth,-INFINITO,+INFINITO,PV,false); Valor_d1 = value_i ; if(Valor_d1 == INFINITO || Valor_d1 == -INFINITO) Valor_d1 = 0; JugD1[0] = '\0'; if(PV[0]) { strcpy(MejorPath,PV); PrintInfo(value,PV); strcpy(JugadaActual,strtok(PV," ")); strcpy(JugD1,JugadaActual); } BFNodeCount[Depth] += NodosVisitados; BFHitCount[Depth]++; Depth++; VAlpha = value-128; VBeta = value+128; Pase = 0; if(Unica) { PrintInfo(value,PV); strcpy(JugadaActual,strtok(PV," u")); Print("bestmove %s\n",JugadaActual); return; } while(1) { if(cancelado) break; if(tiempo_limite) { ini_it = TiempoTranscurrido(); if((ini_it - inicio) > tiempo_limite) // tiempo excedido { break; } } if(LimiteProfundidad) if(Depth > LimiteProfundidad) { if(LimiteProfundidad == 1) PrintInfo(value,PV); break; } if(Depth > MAXDEPTHC) break; SelDepth = 0; if(Depth > 2) Print("info depth %d \n",Depth); hasp = value; ResetHistory(); // nos colocamos en la historia // preparamos la primera evaluacion Taux.CalculaJugadasPosibles(); value = PVS(Depth,-INFINITO,+INFINITO,PV,false); if( cancelado == 1) break; PrintInfo(value,PV); // end of iteration-> get time to depth BFNodeCount[Depth] += NodosVisitados; BFHitCount[Depth]++; if(value == MATE || value == -MATE) { strcpy(JugadaActual,"resign"); break; } PV[0] = '\0'; // reset de la mejor jugada // llevamos la cuenta de iteraciones que damos o recibimos mate if(value < (50-MATE) && value > -MATE) MateCount++; if(value > (MATE-50) && value < MATE) MateCount++; // a partir de 5 iteraciones de mate podemos dar el resultado por bueno if(tiempo_limite) if(MateCount >= 5) break; Depth++; } // hemos terminado de pensar if(JugadaActual[0]) { for(int i=0;JugadaActual[i];i++) if(JugadaActual[i] == '#') JugadaActual[i] = '\0'; if(LimiteProfundidad != 1) Print("bestmove %s\n",JugadaActual); } else { // no tenemos JugadaActual Print("bestmove %s\n",T.JugadasPosibles[0].ToString()); } ValueSearch = value; }
/* ** The Nemesis domain is special - it gets passed ** only half a comment ** and its Pvs are special. */ void Go(Activation_cl *self, VP_clp vp /* IN */, Activation_Reason ar /* IN */ ) { kernel_st *kst = (kernel_st *)self->st; dcb_rw_t *rwp = vp->st; dcb_ro_t *rop = DCB_RW2RO(rwp); ActivationF_cl *actf; TRY { #ifdef __IX86__ ntsc_entkern(); /* There is an NTSC hack that prevents this from being undone. */ #endif /* __IX86__ */ /* Direct all output from Nemesis domain through NTSC (or, on Alpha, direct to the hardware) */ Pvs(err)=Pvs(out)=Pvs(console)=&triv_wr_cl; TRC(printf("Nemesis domain entered.\n")); TRC(printf(" + DCBRO at %p\n", rop)); TRC(printf(" psmask=%qx\n", rop->psmask)); #ifdef __ALPHA__ TRC(printf(" ps=%qx\n", ntsc_rdps())); #endif TRC(printf(" + DCBRW at %p\n", rwp)); TRC(printf(" + Activation clp at %p\n", self)); TRC(printf(" + VP clp at %p\n", vp)); TRC(printf(" + activationsOn=%d\n", VP$ActivationMode(vp))); TRC(printf(" + Activation Reason %d\n", ar)); TRC(printf(" + PVS = %p\n", PVS())); TRC(DUMP_PVS()); { StretchAllocator_clp salloc; StretchAllocator_SizeSeq *sizes; StretchAllocator_StretchSeq *stretches; ThreadsPackage_Stack protoStack; Stretch_clp userStretch; BootDomain_Info *nem_info; ThreadsPackage_clp tp; ThreadF_clp thdf; #ifdef CONFIG_MEMSYS_EXPT SDriverMod_cl *sdmod; StretchTbl_cl *strtab; #define MAX_DESCS 5 Mem_PMemDesc pmem[MAX_DESCS + 1]; Type_Any fany; flink_t *lk; flist_t *cur; int i = 0; /* Create a new stretch driver (physical one for now) */ TRC(printf("Creating initial stretch driver and stretch tab.\n")); sdmod = NAME_FIND("modules>SDriverMod", SDriverMod_clp); strtab = NAME_FIND("sys>StretchTable", StretchTbl_clp); /* Grab the pmem which has been allocated for us by dmgr */ for(lk = rop->finfo.next; lk != &rop->finfo; lk = lk->next) { cur = (flist_t *)lk; pmem[i].start_addr = cur->base; pmem[i].frame_width = cur->fwidth; pmem[i].nframes = cur->npf >> (cur->fwidth - FRAME_WIDTH); pmem[i].attr = 0; if(++i == MAX_DESCS) break; } pmem[i].nframes = 0; /* terminate array */ ANY_INIT(&fany, Frames_clp, rop->frames); Pvs(sdriver) = SDriverMod$NewPhysical(sdmod, vp, Pvs(heap), strtab, pmem, &fany); #endif /* Add our personal frames closure into the sys context */ /* XXX SDE: I'm not convinced that this is a good idea; the Nemesis domain (and all other domains) should have a bit of private namespace for this. I was bitten once by a domain using the Nemesis domain's Frames closure directly because its own hadn't overridden it in the namespace. */ CX_ADD("sys>Frames", rop->frames, Frames_clp); TRC(eprintf (" + Finding Nemesis StretchAllocator\n")); salloc = NAME_FIND("sys>StretchAllocator", StretchAllocator_clp); TRC(eprintf (" + StretchAlloc = %p\n", salloc)); TRC(eprintf (" + Finding parameters\n")); nem_info= NAME_FIND("progs>Nemesis", BootDomain_InfoP); sizes = SEQ_NEW(StretchAllocator_SizeSeq, 3, Pvs(heap)); SEQ_ELEM(sizes, 0) = FRAME_SIZE; /* for guard page */ SEQ_ELEM(sizes, 1) = nem_info->stackWords*sizeof(word_t); SEQ_ELEM(sizes, 2) = nem_info->pHeapWords*sizeof(word_t); TRC(eprintf (" + Allocating Stretches\n")); stretches = STR_NEWLIST_SALLOC(salloc, sizes); protoStack.guard = SEQ_ELEM(stretches, 0); protoStack.stretch = SEQ_ELEM(stretches, 1); userStretch = SEQ_ELEM(stretches, 2); TRC(eprintf (" + Freeing SEQs\n")); SEQ_FREE(sizes); SEQ_FREE(stretches); #ifdef CONFIG_MEMSYS_EXPT /* Bind and map the stack */ { Stretch_Size sz; addr_t stackva; int npages; TRC(printf("+ Binding and mapping stack.\n")); stackva = STR_RANGE(protoStack.stretch, &sz); npages = sz >> PAGE_WIDTH; while(npages--) { StretchDriver$Map(Pvs(sdriver), protoStack.stretch, stackva); stackva += PAGE_SIZE; } } #endif TRC(printf(" + Setting protection\n")); SALLOC_SETGLOBAL(salloc, protoStack.guard, 0); /* XXX PRB Global write is a bit dodgy to say the least! */ SALLOC_SETGLOBAL(salloc, protoStack.stretch, SET_ELEM(Stretch_Right_Read) | SET_ELEM(Stretch_Right_Write) ); SALLOC_SETGLOBAL(salloc, userStretch, SET_ELEM(Stretch_Right_Read) | SET_ELEM(Stretch_Right_Write) ); TRC(printf(" + Finding ThreadsPackage\n")); tp = NAME_FIND("modules>NonPreemptiveThreads",ThreadsPackage_clp); TRC(printf(" + ThreadsPackage = %p\n", tp)); if(!(thdf = ThreadsPackage$New(tp, (addr_t)&NemesisMainThread, (addr_t)kst, &protoStack, userStretch, nem_info->stackWords*sizeof(word_t), (Pervasives_Init *)PVS(), &actf))) { TRC(printf("Nemesis: can't get threads.\n")); ntsc_halt(); } /* Set ourselves up to handle memory faults */ /* first get/set an event channel for fault notification */ rwp->mm_ep = VP$AllocChannel(Pvs(vp)); #if defined(CONFIG_MEMSYS_STD) || defined(CONFIG_MEMSYS_EXPT) { MMNotifyMod_cl *mmnmod; MMNotify_cl *mmnfy; StretchTbl_clp strtable; #ifdef CONFIG_MEMSYS_EXPT /* get the stretch table */ TRC(eprintf (" + Finding StretchTable\n")); strtable = NAME_FIND("sys>StretchTable", StretchTbl_clp); #else strtable = (StretchTbl_cl *)NULL; #endif mmnmod = NAME_FIND("modules>MMNotifyMod", MMNotifyMod_clp); mmnfy = MMNotifyMod$New(mmnmod, vp, Pvs(heap), strtable); CX_ADD("sys>MMNotify", mmnfy, MMNotify_clp); ActivationF$Attach(actf, (ChannelNotify_cl *)mmnfy, rwp->mm_ep); } #endif /* for non expt, we do all this with a mmentry in main thd */ } TRC(printf(" + yielding to main thread.\n")); VP$ActivationsOn(Pvs(vp)); VP$Yield(Pvs(vp)); } CATCH_Context$NotFound(name) { printf("Caught execption Context$NotFound(%s)\n", name); } CATCH_ALL { printf("Caught exception %s\n", exn_ctx.cur_exception); } ENDTRY; /* XXX we are not happy here; for now, just halt. */ printf("\nNemesis: Much bogosity!!! halting.\n"); ntsc_dbgstop(); }
int PVS(const uint64_t P, const uint64_t O, uint64_t& NodeCounter, const int alpha, const int beta, const int selectivity, const int depth, const int empties, CLine* pline) { assert((P & O) == 0); assert(-64 <= alpha); assert(alpha <= 64); assert(-64 <= beta ); assert(beta <= 64); assert(alpha <= beta); assert(0 <= depth); assert(depth <= 60); assert(0 <= empties); assert(empties <= 60); assert(empties == Empties(P, O)); assert(depth <= empties); if (depth <= 2 && depth < empties) { if (depth == 2) return Midgame::PVS_2(P, O, NodeCounter, alpha, beta, pline); if (depth == 1) return Midgame::PVS_1(P, O, NodeCounter, alpha, beta, pline); if (depth == 0) return Midgame::Eval_0(P, O, NodeCounter); } if (empties <= A && depth == empties) return Endgame::PVS_A(P, O, NodeCounter, alpha, beta, empties, pline); int lower = alpha; int score; int bestscore = -65; uint8_t BestMove = 64; uint64_t BitBoardPossible = PossibleMoves(P, O); uint64_t LocalNodeCounter = NodeCounter; CHashTableValueType ttValue; NodeCounter++; if (!BitBoardPossible){ if (HasMoves(O, P)) return -PVS(O, P, NodeCounter, -beta, -alpha, selectivity, depth, empties, pline); else { if (pline) pline->NoMoves(); return EvalGameOver(P, empties); } } if (!pline && StabilityCutoff_PVS(P, O, alpha, score)) return score; if (LookUpTTPV(P, O, ttValue) || LookUpTT(P, O, ttValue)) if (USE_PV_TTCUT && !pline && UseTTValue(ttValue, alpha, beta, depth, selectivity, score)) return score; if (USE_IID && ttValue.PV == 64) // IID { int reduced_depth = (depth == empties) ? depth - A : depth - 2; if (reduced_depth >= 3) { PVS(P, O, NodeCounter, -64, 64, 6, reduced_depth, empties, nullptr); if (LookUpTTPV(P, O, ttValue)) if (USE_PV_TTCUT && !pline && UseTTValue(ttValue, alpha, beta, depth, selectivity, score)) return score; } } CLine * line = nullptr; if (pline && pline->size) line = new CLine(pline->size-1); CMoveList mvList(P, O, NodeCounter, BitBoardPossible, depth, alpha, ttValue, true); for (const auto& mv : mvList) { if (bestscore == -65) score = -PVS(mv.P, mv.O, NodeCounter, -beta, -lower, selectivity, depth-1, empties-1, line); else { score = -ZWS(mv.P, mv.O, NodeCounter, -lower-1, selectivity, depth-1, empties-1); if (score > lower && score < beta) score = -PVS(mv.P, mv.O, NodeCounter, -beta, -lower, selectivity, depth-1, empties-1, line); // OPTIMIZATION: -lower -> -score } if (score > bestscore) { bestscore = score; BestMove = mv.move; if (line) pline->NewPV(mv.move, line); if (score >= beta) break; if (score > lower) lower = score; } } if (empties-1 <= B) { UpdateTTPV(P, O, NodeCounter - LocalNodeCounter, alpha, beta, bestscore, depth, NO_SELECTIVITY, BestMove, mvList.BestMove(), mvList.NextBestMove()); UpdateTT(P, O, NodeCounter - LocalNodeCounter, alpha, beta, bestscore, depth, NO_SELECTIVITY, BestMove, mvList.BestMove(), mvList.NextBestMove()); } else { UpdateTTPV(P, O, NodeCounter - LocalNodeCounter, alpha, beta, bestscore, depth, selectivity, BestMove, mvList.BestMove(), mvList.NextBestMove()); UpdateTT(P, O, NodeCounter - LocalNodeCounter, alpha, beta, bestscore, depth, selectivity, BestMove, mvList.BestMove(), mvList.NextBestMove()); } delete line; return bestscore; }