/* Instrument the move generation machinery so that there are two paths which * can be adapted separately. * @param si root slice of solving machinery * @param side side for which to instrument; pass nr_sides for both sides * @note inserts proxy slices STMoveForPieceGeneratorStandardPath and * STMoveForPieceGeneratorAlternativePath that can be used for adjusting the move * generation */ void move_generator_instrument_for_alternative_paths(slice_index si, Side side) { stip_structure_traversal st; solving_instrument_move_generation(si, side, STMoveForPieceGeneratorPathsJoint); stip_structure_traversal_init(&st,0); stip_structure_traversal_override_single(&st, STMoveForPieceGeneratorPathsJoint, &insert_separator); stip_traverse_structure(si,&st); }
static void insert_type1_dead_end(slice_index si) { stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,0); stip_structure_traversal_override_single(&st,STMove,&instrument_defense); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Create the root slices of a battle branch * @param adapter identifies the adapter slice at the beginning of the branch * @param state address of structure holding state */ void battle_branch_make_root_slices(slice_index adapter, spin_off_state_type *state) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParamListEnd(); { stip_structure_traversal st; stip_structure_traversal_init(&st,state); stip_structure_traversal_override_by_structure(&st, slice_structure_leaf, &leaf_spin_off_copy); stip_structure_traversal_override_by_structure(&st, slice_structure_pipe, &pipe_spin_off_copy); stip_structure_traversal_override_by_structure(&st, slice_structure_branch, &pipe_spin_off_copy); stip_structure_traversal_override_by_structure(&st, slice_structure_fork, &fork_make_root); stip_structure_traversal_override_by_contextual(&st, slice_contextual_binary, &binary_make_root); stip_structure_traversal_override_by_contextual(&st, slice_contextual_conditional_pipe, &conditional_pipe_spin_off_copy); stip_structure_traversal_override_single(&st, STReadyForDefense, &ready_for_defense_make_root); stip_structure_traversal_override_single(&st, STConstraintTester, &constraint_tester_make_root); stip_structure_traversal_override_single(&st, STGoalConstraintTester, &goal_constraint_tester_make_root); stip_structure_traversal_override_single(&st, STReadyForDefense, &ready_for_defense_make_root); stip_structure_traversal_override_single(&st, STEndOfRoot, &serve_as_root_hook); stip_traverse_structure(adapter,&st); } TraceFunctionExit(__func__); TraceFunctionParamListEnd(); }
/* Instrument the solving machinery with move generator slices * @param si identifies root the solving machinery */ void solving_insert_move_generators(slice_index si) { stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,0); stip_structure_traversal_override(&st,solver_inserters,nr_solver_inserters); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void insert_promoters(slice_index si) { stip_structure_traversal st; slice_index landing = no_slice; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,&landing); stip_structure_traversal_override_single(&st,STBeforePawnPromotion,&instrument_promotion); stip_structure_traversal_override_single(&st,STLandingAfterPawnPromotion,&remember_landing); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void instrument(slice_index si) { /* we have to actually play potentially assassinating moves */ stip_instrument_check_validation(si, nr_sides, STValidateCheckMoveByPlayingCapture); { stip_structure_traversal st; stip_structure_traversal_init(&st,0); stip_structure_traversal_override_single(&st, STKingSquareObservationTester, &substitute_all_pieces_observation_tester); stip_traverse_structure(si,&st); } }
/* When counting mating moves, it is not necessary to detect self-check in moves * that don't deliver mate; remove the slices that would detect these * self-checks * @param si identifies slice where to start */ void optimise_away_unnecessary_selfcheckguards(slice_index si) { stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,0); stip_structure_traversal_override_single(&st, STExclusiveChessMatingMoveCounterFork, &remove_guard); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Attempt to apply the postkey play option to the current stipulation * @param root_proxy identifies root proxy slice * @return true iff postkey play option is applicable (and has been * applied) */ static boolean battle_branch_apply_postkeyplay(slice_index root_proxy) { boolean result; slice_index postkey_slice = no_slice; stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",root_proxy); TraceFunctionParamListEnd(); TraceStipulation(root_proxy); stip_structure_traversal_init(&st,&postkey_slice); stip_structure_traversal_override_by_structure(&st, slice_structure_pipe, &move_to_postkey); stip_structure_traversal_override_by_contextual(&st, slice_contextual_testing_pipe, &move_to_postkey); stip_structure_traversal_override_single(&st, STAttackAdapter, &attack_adapter_make_postkeyplay); stip_structure_traversal_override_single(&st, STHelpAdapter, &stip_structure_visitor_noop); stip_traverse_structure_children_pipe(root_proxy,&st); if (postkey_slice==no_slice) result = false; else { link_to_branch(root_proxy,postkey_slice); { slice_index const prototype = alloc_move_inverter_slice(); slice_insertion_insert(root_proxy,&prototype,1); } result = true; } TraceFunctionExit(__func__); TraceFunctionParam("%u",result); TraceFunctionParamListEnd(); return result; }
/* Instrument the stipulation representation with proxy slices marking the * beginning and end of the threat * @param si identifies slice where to start */ void solving_insert_threat_boundaries(slice_index si) { stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,0); stip_structure_traversal_override(&st, threat_boundaries_inserters, nr_threat_boundaries_inserters); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Execute the optimisations planned before and communicated using a series of * invokations of ohneschach_stop_if_check_plan_to_optimise_away_stop() * @param root root slice of the stiptulation */ void ohneschach_stop_if_check_execute_optimisations(slice_index root) { stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",root); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,0); stip_structure_traversal_override_single(&st, STOhneschachStopIfCheckAndNotMate, &optimise_stop); stip_traverse_structure(root,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Produce slices representing set play. * This is supposed to be invoked from within the slice type specific * functions invoked by stip_apply_setplay. * @param adapter identifies the adapter slice into the battle branch * @param state address of structure holding state */ void battle_branch_make_setplay(slice_index adapter, spin_off_state_type *state) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParamListEnd(); { slice_index const start = branch_find_slice(STReadyForDefense, adapter, stip_traversal_context_intro); stip_structure_traversal st; slice_index const notend = branch_find_slice(STNotEndOfBranchGoal, adapter, stip_traversal_context_intro); slice_index const prototype = alloc_pipe(STEndOfRoot); assert(notend!=no_slice); defense_branch_insert_slices(notend,&prototype,1); assert(start!=no_slice); stip_structure_traversal_init(&st,state); st.context = stip_traversal_context_defense; stip_structure_traversal_override_by_structure(&st, slice_structure_pipe, ©_to_setplay); stip_structure_traversal_override_by_structure(&st, slice_structure_branch, ©_to_setplay); stip_structure_traversal_override_by_structure(&st, slice_structure_fork, ©_to_setplay); stip_structure_traversal_override_single(&st,STEndOfRoot,&serve_as_root_hook); stip_traverse_structure(start,&st); TraceValue("%u",state->spun_off[start]); TraceEOL(); state->spun_off[adapter] = state->spun_off[start]; } TraceValue("%u",state->spun_off[adapter]); TraceEOL(); TraceFunctionExit(__func__); TraceFunctionParamListEnd(); }
static void insert_in_branch_guards(slice_index si) { stip_structure_traversal st; in_branch_insertion_state_type state = { no_goal, false, no_side }; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,&state); stip_structure_traversal_override(&st, in_branch_guards_inserters, nr_in_branch_guards_inserters); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Replace immobility tester slices' type * @param si where to start (entry slice into stipulation) */ void immobility_testers_substitute_king_first(slice_index si) { stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); TraceStipulation(si); stip_structure_traversal_init(&st,0); stip_structure_traversal_override_single(&st, STImmobilityTester, &substitute_king_first); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static void insert_guards_in_immobility_testers(slice_index si) { stip_structure_traversal st; boolean in_constraint = false; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,&in_constraint); stip_structure_traversal_override_single(&st, STGoalImmobileReachedTester, &instrument_immobile_reached_tester); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Spin off slices for testing whethere there is a solution * @param si root slice of the stipulation */ void solving_spin_off_testers(slice_index si) { stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); TraceStipulation(si); stip_structure_traversal_init(&st,0); stip_structure_traversal_override_by_structure(&st, slice_structure_pipe, &stip_spin_off_testers_pipe); stip_structure_traversal_override_by_structure(&st, slice_structure_branch, &stip_spin_off_testers_pipe); stip_structure_traversal_override_by_structure(&st, slice_structure_fork, &stip_spin_off_testers_fork); stip_structure_traversal_override_by_structure(&st, slice_structure_leaf, &stip_spin_off_testers_leaf); stip_structure_traversal_override_by_contextual(&st, slice_contextual_binary, &stip_spin_off_testers_binary); stip_structure_traversal_override_by_contextual(&st, slice_contextual_testing_pipe, &stip_spin_off_testers_testing_pipe); stip_structure_traversal_override_by_contextual(&st, slice_contextual_conditional_pipe, &stip_spin_off_testers_conditional_pipe); stip_structure_traversal_override_single(&st,STTemporaryHackFork,&stip_spin_off_testers_pipe_skip); stip_structure_traversal_override_single(&st,STPlaySuppressor,&stip_spin_off_testers_pipe_skip); stip_structure_traversal_override_single(&st,STIfThenElse,&stip_spin_off_testers_if_then_else); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Instrument move generation with a slice type * @param identifies where to start instrumentation * @param side which side (pass nr_sides for both sides) * @param type type of slice with which to instrument moves */ void solving_instrument_move_generation(slice_index si, Side side, slice_type type) { stip_structure_traversal st; insertion_configuration config = { side, type }; TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,&config); stip_structure_traversal_override_single(&st, STGeneratingMovesForPiece, &instrument_generating); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Inialise the solving machinery with Annan Chess * @param si identifies root slice of solving machinery */ void annan_initialise_solving(slice_index si) { TraceFunctionEntry(__func__); TraceFunctionParamListEnd(); solving_instrument_move_generation(si,nr_sides,STAnnanMovesForPieceGenerator); { stip_structure_traversal st; stip_structure_traversal_init(&st,0); stip_structure_traversal_override_single(&st, STEnforceObserverWalk, &substitute_enforce_annanised_walk); stip_traverse_structure(si,&st); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
static boolean is_attack_constrained(slice_index si, stip_structure_traversal *st) { boolean result = false; /* we needed a nested traversal because in semi-r#n option postkey, * STEndOfBranchForced precedes STConstraintsTester */ stip_structure_traversal st_nested; stip_structure_traversal_init(&st_nested,&result); st_nested.context = st->context; stip_structure_traversal_override_by_structure(&st_nested, slice_structure_fork, &stip_traverse_structure_children); stip_structure_traversal_override_single(&st_nested, STConstraintTester, &detect_constrained_attack); stip_traverse_structure(si,&st_nested); return result; }
/* Instrument stipulation with STDegenerateTree slices * @param si identifies slice where to start */ void solving_insert_degenerate_tree_guards(slice_index si) { stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); TraceStipulation(si); stip_structure_traversal_init(&st,0); stip_structure_traversal_override_single(&st, STReadyForAttack, °enerate_tree_inserter_attack); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Detect whether a goal implies immobility of the "goaled" side * @param si identifies entry slice to the goal testing machinery * @return true iff the goal implies immobility */ static boolean does_goal_imply_immobility(slice_index si) { boolean result = false; stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,&result); stip_structure_traversal_override(&st, end_of_branch_goal_immobility_detectors, nr_end_of_branch_goal_immobility_detectors); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Has the input branch already been instrumend with a proofgame solver? * @param start entry into input branch * @return true iff input branch has already been instrumend */ boolean input_is_instrumented_with_proof(slice_index start) { boolean result = false; stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",start); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,&result); stip_structure_traversal_override_single(&st,STProofSolverBuilder,&report_instrumented); stip_structure_traversal_override_single(&st,STAToBSolverBuilder,&report_instrumented); stip_structure_traversal_override_single(&st,STStartOfCurrentTwin,&stip_structure_visitor_noop); stip_traverse_structure(start,&st); TraceFunctionExit(__func__); TraceFunctionResult("%u",result); TraceFunctionResultEnd(); return result; }
/* Remove goal checker slices that we know can't possibly be met * @param si identifies entry slice to stipulation */ void solving_remove_irrelevant_constraints(slice_index si) { stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); TraceStipulation(si); stip_structure_traversal_init(&st,0); stip_structure_traversal_override(&st, unsatisfiable_goal_checker_removers, nr_unsatisfiable_goal_checker_removers); stip_traverse_structure(si,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Substitute the default slice playing the last retro move by a slice of a * different type * @param solving_machinery index of entry slice into solving machinery * @param type type of the substitute */ void retro_substitute_last_move_player(slice_index solving_machinery, slice_type type) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",solving_machinery); TraceEnumerator(slice_type,type); TraceFunctionParamListEnd(); { stip_structure_traversal st; stip_structure_traversal_init(&st,&type); stip_structure_traversal_override_single(&st, STRetroPlayNullMove, &substitute); stip_traverse_structure(solving_machinery,&st); } TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Instrument the solving machinery with the necessary STAvoidUnusable slices * @param root_slice identifies root slice of the solving machinery */ void solving_insert_avoid_unsolvable_forks(slice_index root_slice) { stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",root_slice); TraceFunctionParamListEnd(); stip_structure_traversal_init(&st,0); stip_structure_traversal_override_by_contextual(&st, slice_contextual_end_of_branch, &insert_avoid_unsolvable); stip_structure_traversal_override(&st, avoid_unusable_inserters, nr_avoid_unusable_inserters); stip_traverse_structure(root_slice,&st); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* 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(); }
/* 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(); }
/* 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(); }
/* 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(); }
/* Create the root slices of a help branch * @param adapter identifies the adapter slice at the beginning of the branch * @param state address of structure holding state */ void help_branch_make_root_slices(slice_index adapter, spin_off_state_type *state) { TraceFunctionEntry(__func__); TraceFunctionParam("%u",adapter); TraceFunctionParamListEnd(); { stip_structure_traversal st; TraceStipulation(adapter); stip_structure_traversal_init(&st,state); stip_structure_traversal_override_by_structure(&st, slice_structure_pipe, &pipe_spin_off_copy); stip_structure_traversal_override_by_structure(&st, slice_structure_branch, &pipe_spin_off_copy); stip_structure_traversal_override_by_contextual(&st, slice_contextual_binary, &binary_make_root); stip_structure_traversal_override_by_structure(&st, slice_structure_fork, &fork_make_root); stip_structure_traversal_override_by_contextual(&st, slice_contextual_conditional_pipe, &conditional_pipe_spin_off_copy); stip_structure_traversal_override_single(&st, STConstraintTester, &constraint_tester_make_root); stip_structure_traversal_override_single(&st,STEndOfRoot,&serve_as_root_hook); stip_traverse_structure(adapter,&st); } TraceValue("%u\n",state->spun_off[adapter]); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }
/* Initialise solving in Superguards * @param si identifies the root slice of the stipulation */ void superguards_initialise_solving(slice_index si) { stip_structure_traversal st; TraceFunctionEntry(__func__); TraceFunctionParam("%u",si); TraceFunctionParamListEnd(); TraceStipulation(si); stip_structure_traversal_init(&st,0); stip_structure_traversal_override_single(&st, STDoneGeneratingMoves, &insert_remover); stip_traverse_structure(si,&st); stip_instrument_observation_validation(si,nr_sides,STSuperguardsRemoveIllegalCaptures); stip_instrument_check_validation(si,nr_sides,STSuperguardsRemoveIllegalCaptures); TraceFunctionExit(__func__); TraceFunctionResultEnd(); }