/* Try to solve in solve_nr_remaining half-moves. * @param si slice index * @note assigns solve_result the length of solution found and written, i.e.: * previous_move_is_illegal the move just played is illegal * this_move_is_illegal the move being played is illegal * immobility_on_next_move the moves just played led to an * unintended immobility on the next move * <=n+1 length of shortest solution found (n+1 only if in next * branch) * n+2 no solution found in this branch * n+3 no solution found in next branch * (with n denominating solve_nr_remaining) */ void stoponshortsolutions_solve(slice_index si) { slice_index const initialiser = SLICE_NEXT2(si); TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (has_short_solution_been_found_in_phase(initialiser)) solve_result = MOVE_HAS_NOT_SOLVED_LENGTH(); else { pipe_solve_delegate(si); if (solve_result<=MOVE_HAS_SOLVED_LENGTH() && solve_nr_remaining<SLICE_U(si).branch.length) short_solution_found(initialiser); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void instrument_no_rebirth(slice_index si, stip_structure_traversal *st) { TraceFunctionEntry(__func__); TraceValue("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children(si,st); { slice_index const prototypes[] = { alloc_pipe(STMarsCirceRememberNoRebirth), alloc_pipe(STMoveGeneratorRejectCaptures) }; enum { nr_prototypes = sizeof prototypes / sizeof prototypes[0] }; slice_insertion_insert_contextually(si,st->context,prototypes,nr_prototypes); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Determine the rank of a slice type * @param type defense slice type * @return rank of type; nr_defense_slice_rank_order_elmts if the rank can't * be determined */ static unsigned int get_goal_slice_rank(slice_type type) { unsigned int result = no_goal_slice_type; unsigned int i; TraceFunctionEntry(__func__); TraceEnumerator(slice_type,type,""); TraceFunctionParamListEnd(); for (i = 0; i!=nr_goal_slice_rank_order_elmts; ++i) if (goal_slice_rank_order[i]==type) { result = i; break; } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Instrument the solving machinery with STContinuationSolver slices * @param root_slice root slice of the solving machinery */ void solving_insert_continuation_solvers(slice_index si) { stip_structure_traversal st; boolean attack_played = false; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,&attack_played); stip_structure_traversal_override_by_contextual(&st, slice_contextual_conditional_pipe, &stip_traverse_structure_children_pipe); stip_structure_traversal_override(&st, continuation_solver_inserters, nr_continuation_solver_inserters); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static boolean is_imitator_pos_occupied(void) { boolean result = false; unsigned int i; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); for (i=0; i!=being_solved.number_of_imitators; ++i) if (!is_square_empty(being_solved.isquare[i])) { TraceSquare(being_solved.isquare[i]);TraceEOL(); result = true; break; } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Instrument the solving machinery for BlackChecks * @param si identifies root slice of stipulation */ void blackchecks_initialise_solving(slice_index si) { stip_structure_traversal st; slice_index landing = no_slice; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,&landing); stip_structure_traversal_override_single(&st,STGoalReachedTester,&stip_structure_visitor_noop); stip_structure_traversal_override_single(&st,STMove,&instrument_move); stip_structure_traversal_override_single(&st,STGeneratingMoves,&instrument_move_generator); stip_structure_traversal_override_single(&st, STLandingAfterMovingPieceMovement, &remember_landing); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Instrument the current problem with option maxsolutions * @param si identifies the slice where to start instrumenting * @param max_nr_solutions_per_phase */ void maxsolutions_instrument_problem(slice_index si, unsigned int i) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParam("%u",i); TraceFunctionParamListEnd(); { slice_index const interruption = branch_find_slice(STPhaseSolvingIncomplete, si, stip_traversal_context_intro); slice_index const prototype = alloc_pipe(STMaxSolutionsProblemInstrumenter); SLICE_NEXT2(prototype) = interruption; assert(interruption!=no_slice); slice_insertion_insert(si,&prototype,1); max_nr_solutions_per_phase = i; } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Determine whether the move just played in ply nbply is in a table * @param t table identifier * @return true iff the move just played is in table t */ boolean is_current_move_in_table(table t) { table_position i; boolean result = false; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); assert(current_position[t]>=current_position[t-1]); for (i = current_position[t-1]+1; i<=current_position[t]; i++) if (moves_equal(&tables_stack[i])) { result = true; break; } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Spin a STContraintSolver slice off a STContraintTester sliceto add it to the * root or set play branch * @param si identifies (non-root) slice * @param st address of structure representing traversal */ void constraint_tester_make_root(slice_index si, stip_structure_traversal *st) { spin_off_state_type * const state = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children_pipe(si,st); if (state->spun_off[SLICE_NEXT1(si)]!=no_slice) { state->spun_off[si] = alloc_constraint_solver_slice(stip_deep_copy(SLICE_NEXT2(si))); link_to_branch(state->spun_off[si],state->spun_off[SLICE_NEXT1(si)]); } TraceValue("%u\n",state->spun_off[si]); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void genmove(void) { unsigned int i; square square_h = square_h8; Side const side = trait[nbply]; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); for (i = nr_rows_on_board; i>0; i--, square_h += dir_down) { unsigned int j; square sq_departure = square_h; for (j = nr_files_on_board; j>0; j--, sq_departure += dir_left) if (TSTFLAG(being_solved.spec[sq_departure],side)) generate_moves_for_piece(sq_departure); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void determine_king_placement(Side trait_ply) { TraceFunctionEntry(__func__); TraceEnumerator(Side,trait_ply,""); TraceFunctionParamListEnd(); if (post_move_iteration_id[nbply]!=prev_post_move_iteration_id[nbply]) { king_placement[nbply] = square_a1-1; is_mate_square_dirty[nbply] = true; } if (is_mate_square_dirty[nbply]) { advance_mate_square(trait_ply); is_mate_square_dirty[nbply] = false; } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void instrument_generating(slice_index si, stip_structure_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children_pipe(si,st); { insertion_configuration const * config = st->param; if (config->side==nr_sides || config->side==SLICE_STARTER(si)) { slice_index const prototype = alloc_pipe(config->type); move_generation_branch_insert_slices_impl(si,&prototype,1,si); dealloc_slice(prototype); } } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Try to solve in solve_nr_remaining half-moves. * @param si slice index * @note assigns solve_result the length of solution found and written, i.e.: * previous_move_is_illegal the move just played is illegal * this_move_is_illegal the move being played is illegal * immobility_on_next_move the moves just played led to an * unintended immobility on the next move * <=n+1 length of shortest solution found (n+1 only if in next * branch) * n+2 no solution found in this branch * n+3 no solution found in next branch * (with n denominating solve_nr_remaining) */ void extinction_extincted_tester_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); { Side const side_in_check = SLICE_STARTER(si); piece_walk_type const capturee = find_capturee(); TraceWalk(capturee); TraceEnumerator(Side,side_in_check,"\n"); pipe_this_move_doesnt_solve_if(si, capturee==Empty || being_solved.number_of_pieces[side_in_check][capturee]!=0); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void insert_make_generator_avoid_pawn_to_baseline(slice_index si, stip_structure_traversal *st) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children(si,st); { slice_index const prototypes[] = { alloc_pipe(STTakeAndMakeGenerateMake), alloc_pipe(STTakeAndMakeAvoidPawnMakeToBaseLine), }; slice_insertion_insert_contextually(si,st->context,prototypes,2); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Activate mummer for a side and define the length measurer to be used. * @param side Side for which to activate mummer * @param measurer length measurer to be used * @return false iff mummer was already activated for side */ boolean mummer_set_length_measurer(Side side, mummer_length_measurer_type measurer) { boolean result; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); if (mummer_measure_length[side]==0) { mummer_measure_length[side] = measurer; result = true; } else result = false; TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Try to solve in solve_nr_remaining half-moves. * @param si slice index * @note assigns solve_result the length of solution found and written, i.e.: * previous_move_is_illegal the move just played is illegal * this_move_is_illegal the move being played is illegal * immobility_on_next_move the moves just played led to an * unintended immobility on the next move * <=n+1 length of shortest solution found (n+1 only if in next * branch) * n+2 no solution found in this branch * n+3 no solution found in next branch * (with n denominating solve_nr_remaining) */ void find_attack_solve(slice_index si) { stip_length_type result_intermediate = MOVE_HAS_NOT_SOLVED_LENGTH(); TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); while (encore() && result_intermediate>MOVE_HAS_SOLVED_LENGTH()) { pipe_solve_delegate(si); assert(slack_length<=solve_result || solve_result==this_move_is_illegal); if (slack_length<solve_result && solve_result<result_intermediate) result_intermediate = solve_result; } solve_result = result_intermediate; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Validate an observation according to Ultra-Mummer * @return true iff the observation is valid */ boolean ultra_mummer_validate_observation(slice_index si) { Side const side_observing = trait[nbply]; boolean result; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); conditional_pipe_solve_delegate(temporary_hack_ultra_mummer_length_measurer[side_observing]); result = (*mummer_measure_length[side_observing])()==mum_length[nbply]; if (result) result = pipe_validate_observation_recursive_delegate(si); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Try to solve in solve_nr_remaining half-moves. * @param si slice index * @note assigns solve_result the length of solution found and written, i.e.: * previous_move_is_illegal the move just played is illegal * this_move_is_illegal the move being played is illegal * immobility_on_next_move the moves just played led to an * unintended immobility on the next move * <=n+1 length of shortest solution found (n+1 only if in next * branch) * n+2 no solution found in this branch * n+3 no solution found in next branch * (with n denominating solve_nr_remaining) */ void find_defense_solve(slice_index si) { stip_length_type result_intermediate = immobility_on_next_move; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); while (result_intermediate<=MOVE_HAS_SOLVED_LENGTH() && encore()) { pipe_solve_delegate(si); assert(slack_length<=solve_result || solve_result==this_move_is_illegal); if (result_intermediate<solve_result) result_intermediate = solve_result; } solve_result = result_intermediate; TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static boolean compareProofPieces(void) { boolean result = true; unsigned int i; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); for (i = 0; i<ProofNbrAllPieces; ++i) if (target_pieces[i].type!=get_walk_of_piece_on_square(target_pieces[i].pos) || target_pieces[i].spec!=(being_solved.spec[target_pieces[i].pos]&PieSpMask)) { result = false; break; } TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
void remember_detector(slice_index si, stip_structure_traversal *st) { instrumentation_state_type * const state = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_traverse_structure_children(si,st); if (SLICE_STARTER(si)==no_side /* just inserted */ && state->past_detector==no_slice) { SLICE_STARTER(si) = state->side; state->past_detector = alloc_proxy_slice(); pipe_append(si,state->past_detector); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void insert_guard_and_counter(slice_index si, stip_structure_traversal *st) { insertion_struct * const insertion = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); { slice_index const prototypes[] = { alloc_maxsolutions_guard_slice(), alloc_maxsolutions_counter_slice(insertion->incomplete) }; enum { nr_prototypes = sizeof prototypes / sizeof prototypes[0] }; slice_insertion_insert(si,prototypes,nr_prototypes); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Try to solve in solve_nr_remaining half-moves. * @param si slice index * @note assigns solve_result the length of solution found and written, i.e.: * previous_move_is_illegal the move just played is illegal * this_move_is_illegal the move being played is illegal * immobility_on_next_move the moves just played led to an * unintended immobility on the next move * <=n+1 length of shortest solution found (n+1 only if in next * branch) * n+2 no solution found in this branch * n+3 no solution found in next branch * (with n denominating solve_nr_remaining) */ void ohneschach_detect_undecidable_goal_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); TraceValue("%u",nbply); TraceValue("%u",ohneschach_undecidable_goal_detected[nbply+1]); TraceEOL(); if (ohneschach_undecidable_goal_detected[nbply+1]) { ohneschach_undecidable_goal_detected[nbply+1] = false; solve_result = previous_move_is_illegal; output_plaintext_message(ChecklessUndecidable); } else pipe_solve_delegate(si); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Inialise solving in Shielded kings * @param si identifies the root slice of the solving machinery */ void shielded_kings_initialise_solving(slice_index si) { stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,0); stip_structure_traversal_override_single(&st, STDoneGeneratingMoves, &insert_remover); stip_traverse_structure(si,&st); // needed for combination with transmuting kings etc. stip_instrument_observation_validation(si,nr_sides,STShieldedKingsRemoveIllegalCaptures); stip_instrument_check_validation(si,nr_sides,STShieldedKingsRemoveIllegalCaptures); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Try to solve in solve_nr_remaining half-moves. * @param si slice index * @note assigns solve_result the length of solution found and written, i.e.: * previous_move_is_illegal the move just played is illegal * this_move_is_illegal the move being played is illegal * immobility_on_next_move the moves just played led to an * unintended immobility on the next move * <=n+1 length of shortest solution found (n+1 only if in next * branch) * n+2 no solution found in this branch * n+3 no solution found in next branch * (with n denominating solve_nr_remaining) */ void reset_unsolvable_solve(slice_index si) { stip_length_type const save_max_unsolvable = max_unsolvable; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); max_unsolvable = slack_length; TraceValue("->%u",max_unsolvable); TraceEOL(); pipe_solve_delegate(si); max_unsolvable = save_max_unsolvable; TraceValue("->%u",max_unsolvable); TraceEOL(); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Try to solve in solve_nr_remaining half-moves. * @param si slice index * @note assigns solve_result the length of solution found and written, i.e.: * previous_move_is_illegal the move just played is illegal * this_move_is_illegal the move being played is illegal * immobility_on_next_move the moves just played led to an * unintended immobility on the next move * <=n+1 length of shortest solution found (n+1 only if in next * branch) * n+2 no solution found in this branch * n+3 no solution found in next branch * (with n denominating solve_nr_remaining) */ void exclusive_chess_undecidable_writer_tree_solve(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (is_current_move_in_table(exclusive_chess_undecidable_continuations[parent_ply[nbply]])) SignalExclusiveRefutedUndecidable(); else { pipe_solve_delegate(si); if (solve_result==previous_move_has_solved && exclusive_chess_nr_continuations_reaching_goal[parent_ply[nbply]]<2 && table_length(exclusive_chess_undecidable_continuations[parent_ply[nbply]])+exclusive_chess_nr_continuations_reaching_goal[parent_ply[nbply]]>1) SignalChecklessUndecidable(); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static boolean is_goal_move_oriented(slice_index goal_reached_tester, stip_structure_traversal *st) { boolean result = true; stip_structure_traversal st_nested; TraceFunctionEntry(__func__); TraceFunctionParam("%u",goal_reached_tester); TraceFunctionParamListEnd(); stip_structure_traversal_init_nested(&st_nested,st,&result); stip_structure_traversal_override(&st_nested, goal_move_oriented_testers, nr_goal_move_oriented_testers); stip_traverse_structure(goal_reached_tester,&st_nested); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Try to solve in solve_nr_remaining half-moves. * @param si slice index * @note assigns solve_result the length of solution found and written, i.e.: * previous_move_is_illegal the move just played is illegal * this_move_is_illegal the move being played is illegal * immobility_on_next_move the moves just played led to an * unintended immobility on the next move * <=n+1 length of shortest solution found (n+1 only if in next * branch) * n+2 no solution found in this branch * n+3 no solution found in next branch * (with n denominating solve_nr_remaining) */ void marscirce_initialise_reborn_from_generated_solve(slice_index si) { circe_rebirth_context_elmt_type * const context = &circe_rebirth_context_stack[circe_rebirth_context_stack_pointer]; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); context->rebirth_from = curr_generation->departure; context->reborn_walk = move_generation_current_walk; context->reborn_spec = being_solved.spec[context->rebirth_from]; context->relevant_ply = nbply; context->relevant_square = context->rebirth_from; context->relevant_side = advers(trait[context->relevant_ply]); pipe_solve_delegate(si); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void insert_selfcheck_guard_branch(slice_index si, stip_structure_traversal *st) { in_branch_insertion_state_type const * const state = st->param; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); if (!state->is_branch_instrumented) { slice_index const prototype = alloc_selfcheck_guard_slice(); SLICE_STARTER(prototype) = SLICE_STARTER(si); slice_insertion_insert_contextually(si,st->context,&prototype,1); } stip_traverse_structure_children_pipe(si,st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static boolean is_mover_supported_recursive(void) { boolean result; Flags const mask = BIT(trait[nbply])|BIT(Royal); TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); TraceSquare(move_generation_stack[CURRMOVE_OF_PLY(nbply)].capture); TraceEOL(); if (TSTFULLFLAGMASK(being_solved.spec[move_generation_stack[CURRMOVE_OF_PLY(nbply)].capture],mask)) result = true; else result = is_square_observed(EVALUATE(observation)); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Notify the output machinery about a twinning event * @param si identifies the slice that detected the twinning (at the same time * to be used as the starting point of any instrumentation) * @param stage the twinning event * @param continued is the twin continued? */ void output_notify_twinning(slice_index si, twinning_event_type event, boolean continued) { stip_structure_traversal st; notification_struct e = { event, continued }; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParam("%u",event); TraceFunctionParam("%u",continued); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,&e); stip_structure_traversal_override_single(&st,STOutputPlaintextTwinIntroWriterBuilder,¬ify_medium); stip_structure_traversal_override_single(&st,STOutputLaTeXTwinningWriterBuilder,¬ify_medium); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }