示例#1
0
static char *ParseReciEnd(char *tok, slice_index start, slice_index proxy)
{
    slice_index op1;
    slice_index op2;

    TraceFunctionEntry(__func__);
    TraceFunctionParam("%s",tok);
    TraceFunctionParam("%u",start);
    TraceFunctionParam("%u",proxy);
    TraceFunctionParamListEnd();

    op1 = alloc_proxy_slice();
    op2 = alloc_proxy_slice();

    tok = ParseReciGoal(tok,start,op1,op2);
    if (SLICE_NEXT1(op1)!=no_slice && SLICE_NEXT1(op2)!=no_slice)
    {
        slice_index const reci = alloc_and_slice(op1,op2);
        pipe_link(proxy,reci);
    }

    TraceFunctionExit(__func__);
    TraceFunctionResult("%s",tok);
    TraceFunctionResultEnd();
    return tok;
}
示例#2
0
static char *ParseReciGoal(char *tok,
                           slice_index start,
                           slice_index proxy_nonreci,
                           slice_index proxy_reci)
{
    char *result = 0;

    TraceFunctionEntry(__func__);
    TraceFunctionParam("%s",tok);
    TraceFunctionParamListEnd();

    if (*tok=='(')
    {
        char const *closingParenPos = strchr(tok,')');
        if (closingParenPos!=0)
        {
            slice_index const proxy_to_reci = alloc_proxy_slice();
            tok = ParseGoal(tok+1,start,proxy_to_reci);
            if (tok!=0)
            {
                if (tok==closingParenPos)
                {
                    slice_index const proxy_to_nonreci = alloc_proxy_slice();
                    result = ParseGoal(tok+1,start,proxy_to_nonreci);
                    if (result!=NULL)
                    {
                        slice_index const nonreci = SLICE_NEXT1(proxy_to_nonreci);
                        SLICE_STARTER(nonreci) = Black;
                        alloc_reci_end(proxy_nonreci,proxy_reci,
                                       proxy_to_nonreci,proxy_to_reci);
                    }
                }
                else
                    output_plaintext_input_error_message(UnrecStip, 0);
            }
        }
        else
            output_plaintext_input_error_message(UnrecStip, 0);
    }
    else
    {
        slice_index const proxy_to_nonreci = alloc_proxy_slice();
        result = ParseGoal(tok,start,proxy_to_nonreci);
        if (result!=NULL)
        {
            slice_index const nonreci_testing = SLICE_NEXT1(proxy_to_nonreci);
            slice_index const nonreci_tester = SLICE_NEXT1(nonreci_testing);
            slice_index const proxy_to_reci = stip_deep_copy(proxy_to_nonreci);
            alloc_reci_end(proxy_nonreci,proxy_reci,
                           proxy_to_nonreci,proxy_to_reci);
            SLICE_STARTER(nonreci_tester) = Black;
        }
    }

    TraceFunctionExit(__func__);
    TraceFunctionResult("%s",result);
    TraceFunctionResultEnd();
    return result;
}
示例#3
0
/* Insert slices into a goal branch.
 * The inserted slices are copies of the elements of prototypes).
 * Each slice is inserted at a position that corresponds to its predefined rank.
 * @param si identifies starting point of insertion
 * @param prototypes contains the prototypes whose copies are inserted
 * @param nr_prototypes number of elements of array prototypes
 */
static void goal_branch_insert_slices_nested(slice_index si,
                                             slice_index const prototypes[],
                                             unsigned int nr_prototypes)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParam("%u",nr_prototypes);
  TraceFunctionParamListEnd();

  {
    slice_type const prototype_type = SLICE_TYPE(prototypes[0]);
    unsigned int prototype_rank = get_goal_slice_rank(prototype_type);

    if (prototype_rank==no_goal_slice_type)
    {
      if (nr_prototypes>1)
        goal_branch_insert_slices_nested(si,prototypes+1,nr_prototypes-1);
    }
    else
      do
      {
        slice_index const next = SLICE_NEXT1(si);
        if (SLICE_TYPE(next)==STProxy)
          si = next;
        else if (SLICE_TYPE(next)==STOr
                 || SLICE_TYPE(next)==STAnd)
        {
          goal_branch_insert_slices_nested(SLICE_NEXT1(next),
                                           prototypes,nr_prototypes);
          goal_branch_insert_slices_nested(SLICE_NEXT2(next),
                                           prototypes,nr_prototypes);
          break;
        }
        else
        {
          unsigned int const rank_next = get_goal_slice_rank(SLICE_TYPE(next));
          if (rank_next==no_goal_slice_type)
            break;
          else if (rank_next>prototype_rank)
          {
            slice_index const copy = copy_slice(prototypes[0]);
            pipe_append(si,copy);
            if (nr_prototypes>1)
              goal_branch_insert_slices_nested(copy,prototypes+1,nr_prototypes-1);
            break;
          }
          else
            si = next;
        }
      } while (prototype_type!=SLICE_TYPE(si));
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#4
0
/* Traverse operand 1 of a binary slice
 * @param binary_slice identifies the binary slice
 * @param st address of structure defining traversal
 */
void stip_traverse_moves_binary_operand1(slice_index binary_slice,
                                         stip_moves_traversal *st)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",binary_slice);
  TraceFunctionParam("%p",st);
  TraceFunctionParamListEnd();

  if (SLICE_NEXT1(binary_slice)!=no_slice)
    stip_traverse_moves(SLICE_NEXT1(binary_slice),st);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#5
0
/* Parse a move inversion
 * @param tok input token
 * @param start index of entry into solving machinery
 * @param proxy index of branch; no_slice if operator couldn't be parsed
 * @param level nesting level of the operand (0 means top level)
 * @return remainder of input token; 0 if parsing failed
 */
static char *ParseStructuredStip_move_inversion(char *tok,
                                                slice_index start,
                                                slice_index proxy,
                                                expression_type *type,
                                                unsigned int level)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%s",tok);
  TraceFunctionParam("%u",start);
  TraceFunctionParam("%u",proxy);
  TraceFunctionParam("%u",level);
  TraceFunctionParamListEnd();

  tok = ParseStructuredStip_operand(tok+1,start,proxy,type,level);

  {
    slice_index const operand = SLICE_NEXT1(proxy);
    if (tok!=0 && operand!=no_slice)
    {
      slice_index const prototype = alloc_move_inverter_slice();
      slice_insertion_insert(proxy,&prototype,1);
    }
  }

  TraceFunctionExit(__func__);
  TraceFunctionResult("%s",tok);
  TraceFunctionResultEnd();
  return tok;
}
示例#6
0
static void instrument_negated_tester(slice_index si,
                                      stip_structure_traversal *st)
{
  in_branch_insertion_state_type * const state = st->param;

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  if (state->in_goal_tester!=no_goal)
  {
    /* make sure that not_slice doesn't convert previous_move_has_not_solved into
     * previous_move_has_solved if the last move caused a self-check
     */
    slice_index const proxy_not = alloc_proxy_slice();
    slice_index const proxy_selfcheck = alloc_proxy_slice();
    slice_index const guard = alloc_selfcheck_guard_slice();
    slice_index const leaf_selfcheck = alloc_true_slice();
    if (is_goal_move_oriented(SLICE_NEXT1(si),st))
      pipe_link(SLICE_PREV(si),alloc_and_slice(proxy_not,proxy_selfcheck));
    else
      pipe_link(SLICE_PREV(si),alloc_and_slice(proxy_selfcheck,proxy_not));
    pipe_link(proxy_not,si);
    pipe_link(proxy_selfcheck,guard);
    pipe_link(guard,leaf_selfcheck);

    state->is_branch_instrumented = true;
  }
  else
    stip_traverse_structure_children_pipe(si,st);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#7
0
/* Instrument a help branch with a STIfThenElse slice
 * @param adapter identifies adapter slice into the help branch
 */
void help_branch_insert_check_zigzag(slice_index adapter)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",adapter);
  TraceFunctionParamListEnd();

  {
    slice_index const ready = help_branch_locate_ready(adapter);
    slice_index const proxy1 = alloc_proxy_slice();
    slice_index const proxy2 = alloc_proxy_slice();
    slice_index const played = alloc_help_move_played_slice();
    slice_index const condition = alloc_goal_check_reached_tester_slice(goal_applies_to_starter);
    slice_index const jump = alloc_if_then_else_slice(proxy1,proxy2,condition);
    slice_index const landing_proto = alloc_pipe(STCheckZigzagLanding);

    assert(ready!=no_slice);
    pipe_link(condition,alloc_true_slice());
    help_branch_insert_slices(ready,&landing_proto,1);
    pipe_link(proxy2,SLICE_NEXT1(ready));
    pipe_link(proxy1,played);
    pipe_link(ready,jump);

    {
      slice_index const landing = branch_find_slice(STCheckZigzagLanding,
                                                    ready,
                                                    stip_traversal_context_help);
      assert(landing!=no_slice);
      link_to_branch(played,landing);
    }
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#8
0
static void copy_end_of_branch_goal_if_necessary(slice_index si, stip_structure_traversal *st)
{
  stip_deep_copies_type * const copies = st->param;

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  {
    slice_index const tester = branch_find_slice(STGoalReachedTester,SLICE_NEXT2(si),st->context);
    if (tester==no_slice
        /* avoid considering moves that lead to self-check illegal if they reach the goal: */
        || branch_find_slice(STSelfCheckGuard,SLICE_NEXT2(tester),st->context)==no_slice)
      regular_deep_copy_end_of_branch_goal(si,st);
    else
    {
      /* Rely on the tests in the goal reached tester: */
      (*copies)[si] = alloc_proxy_slice();
      stip_traverse_structure_children_pipe(si,st);
      pipe_link((*copies)[si],(*copies)[SLICE_NEXT1(si)]);
    }
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#9
0
/* Parse a structured stipulation (keyword sstipulation)
 * @param start index of entry into solving machinery
 * @return remainder of input token; 0 if parsing failed
 */
char *ParseStructuredStip(char *tok, slice_index start)
{
  slice_index const root_slice_hook = alloc_proxy_slice();
  Side starter;

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%s",tok);
  TraceFunctionParam("%u",root_slice_hook);
  TraceFunctionParamListEnd();

  stipulation_reset();

  starter = ParseStructuredStip_starter(tok);
  if (starter!=no_side)
  {
    expression_type type;
    tok = ReadNextTokStr();
    tok = ParseStructuredStip_expression(tok,start,root_slice_hook,&type,0);
    if (tok==0)
      tok = ReadNextTokStr();
    else if (SLICE_NEXT1(root_slice_hook)!=no_slice)
    {
      solving_impose_starter(root_slice_hook,starter);
      move_effect_journal_do_insert_sstipulation(start,root_slice_hook);
    }
  }

  /* signal to our caller that the stipulation has changed */
  SLICE_STARTER(root_slice_hook) = no_side;

  TraceFunctionExit(__func__);
  TraceFunctionResult("%s",tok);
  TraceFunctionResultEnd();
  return tok;
}
示例#10
0
/* Create a shallow copy of the visited fork slice
 * @param si visited slice
 * @param st structure representing the copying traversal
 */
static void copy_shallow(slice_index si, stip_structure_traversal *st)
{
  stip_deep_copies_type * const copies = st->param;

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  assert((*copies)[si]==no_slice);
  (*copies)[si] = copy_slice(si);

  stip_traverse_structure_children_pipe(si,st);

  if (SLICE_NEXT1(si)!=no_slice)
    link_to_branch((*copies)[si],(*copies)[SLICE_NEXT1(si)]);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#11
0
/* Add the copy of a slice into the set play branch
 * @param si slice index
 * @param st state of traversal
 */
static void copy_to_setplay(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);
  TraceValue("%u",state->spun_off[SLICE_NEXT1(si)]);
  TraceEOL();

  state->spun_off[si] = copy_slice(si);
  link_to_branch(state->spun_off[si],state->spun_off[SLICE_NEXT1(si)]);
  TraceValue("%u",state->spun_off[si]);
  TraceEOL();

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#12
0
/* 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 substitute_king_first(slice_index si, stip_structure_traversal *st)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  assert(SLICE_STARTER(si)!=no_side);

  stip_traverse_structure_children_pipe(si,st);

  /* this optimisation doesn't work if an ultra-mummer condition applies
   * to the side to be immobilised */
  if (mummer_strictness[SLICE_STARTER(si)]<=mummer_strictness_regular)
  {
    slice_index const proxy1 = alloc_proxy_slice();
    slice_index const proxy2 = alloc_proxy_slice();
    slice_index const king_branch = SLICE_NEXT1(si);
    slice_index const nonking_branch = stip_deep_copy(king_branch);
    slice_index const king_move_tester = alloc_pipe(STImmobilityTester);
    slice_index const nonking_move_tester = alloc_pipe(STImmobilityTester);

    pipe_link(si,alloc_and_slice(proxy1,proxy2));

    pipe_link(proxy1,king_move_tester);
    link_to_branch(king_move_tester,king_branch);

    {
      slice_index const generator = branch_find_slice(STMoveGenerator,
                                                      king_branch,
                                                      stip_traversal_context_intro);
      assert(generator!=no_slice);
      pipe_substitute(generator,alloc_king_move_generator_slice());
    }

    pipe_link(proxy2,nonking_move_tester);
    link_to_branch(nonking_move_tester,nonking_branch);

    {
      slice_index const generator = branch_find_slice(STMoveGenerator,
                                                      nonking_branch,
                                                      stip_traversal_context_intro);
      assert(generator!=no_slice);
      pipe_substitute(generator,alloc_non_king_move_generator_slice());
    }

    pipe_remove(si);
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#14
0
static void stip_traverse_moves_pipe(slice_index si, stip_moves_traversal *st)
{
  slice_index const next = SLICE_NEXT1(si);

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  assert(next!=no_slice);
  stip_traverse_moves(next,st);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#15
0
文件: fork.c 项目: Die9teWoge/popeye
/* Callback to stip_spin_off_testers
 * Spin a tester slice off a fork slice
 * @param si identifies the testing pipe slice
 * @param st address of structure representing traversal
 */
void stip_spin_off_testers_fork(slice_index si, stip_structure_traversal *st)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  SLICE_TESTER(si) = copy_slice(si);
  stip_traverse_structure_children(si,st);
  link_to_branch(SLICE_TESTER(si),SLICE_TESTER(SLICE_NEXT1(si)));
  SLICE_NEXT2(SLICE_TESTER(si)) = SLICE_TESTER(SLICE_NEXT2(si));

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#16
0
/* Spin a copy off a conditional pipe to add it to the root or set play branch
 * @param si identifies (non-root) slice
 * @param st address of structure representing traversal
 */
void conditional_pipe_spin_off_copy(slice_index si,
                                    stip_structure_traversal *st)
{
  spin_off_state_type * const state = st->param;

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  state->spun_off[si] = copy_slice(si);

  stip_traverse_structure_children_pipe(si,st);

  if (state->spun_off[SLICE_NEXT1(si)]==no_slice)
  {
    dealloc_slice(state->spun_off[si]);
    state->spun_off[si] = no_slice;
  }
  else
    link_to_branch(state->spun_off[si],state->spun_off[SLICE_NEXT1(si)]);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#17
0
/* Produce slices representing set play.
 * @param adapter identifies the adapter slice at the beginning of the branch
 * @param state address of structure holding state
 */
void series_branch_make_setplay(slice_index adapter, spin_off_state_type *state)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",adapter);
  TraceFunctionParamListEnd();

  {
    slice_index const next = SLICE_NEXT1(adapter);
    slice_index const prototypes[] =
    {
      alloc_help_adapter_slice(0,0),
      alloc_pipe(STEndOfRoot)
    };
    enum { nr_prototypes = sizeof prototypes / sizeof prototypes[0] };
    help_branch_insert_slices(next,prototypes,nr_prototypes);

    {
      slice_index const set_adapter = branch_find_slice(STHelpAdapter,
                                                        next,
                                                        stip_traversal_context_help);
      assert(set_adapter!=no_slice);
      if (SLICE_TYPE(SLICE_NEXT1(set_adapter))==STDeadEnd)
        ; /* set play not applicable */
      else
        help_branch_make_root_slices(set_adapter,state);
      TraceValue("%u\n",state->spun_off[set_adapter]);
      state->spun_off[adapter] = state->spun_off[set_adapter];
      pipe_remove(set_adapter);
    }
  }

  TraceValue("%u\n",state->spun_off[adapter]);

  TraceFunctionExit(__func__);
  TraceFunctionParamListEnd();
}
示例#18
0
static void skip_copying(slice_index si, stip_structure_traversal *st)
{
  stip_deep_copies_type * const copies = st->param;

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  (*copies)[si] = alloc_proxy_slice();
  stip_traverse_structure_children_pipe(si,st);
  pipe_link((*copies)[si],(*copies)[SLICE_NEXT1(si)]);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#19
0
static void stip_traverse_moves_fork_on_remaining(slice_index si,
                                                  stip_moves_traversal *st)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  if (st->remaining<=SLICE_U(si).fork_on_remaining.threshold)
    stip_traverse_moves(SLICE_NEXT2(si),st);
  else
    stip_traverse_moves(SLICE_NEXT1(si),st);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#20
0
static void connect_solver_to_tester(slice_index si, stip_structure_traversal *st)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  if (st->activity==stip_traversal_activity_solving)
  {
    assert(SLICE_TESTER(SLICE_PREV(si))!=no_slice);
    SLICE_TESTER(si) = SLICE_NEXT1(SLICE_TESTER(SLICE_PREV(si)));
  }

  stip_traverse_structure_children_pipe(si,st);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#21
0
static slice_index make_mate_tester_fork(Side side)
{
  slice_index result;

  if (CondFlag[exclusive] || CondFlag[republican])
  {
    Goal const mate_goal = { goal_mate, initsquare };
    slice_index const mate_tester = alloc_goal_mate_reached_tester_system();
    result = alloc_goal_reached_tester_slice(mate_goal,mate_tester);
    dealloc_slice(SLICE_NEXT1(result));
    solving_impose_starter(result,side);
  }
  else
    result = alloc_proxy_slice();

  return result;
}
示例#22
0
/* Instrument a battle branch with a STIfThenElse slice providing a
 * shortcut for the defense moe
 * @param adapter identifies adapter slice into the battle branch
 */
void battle_branch_insert_defense_check_zigzag(slice_index adapter)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",adapter);
  TraceFunctionParamListEnd();

  {
    slice_index const ready = branch_find_slice(STReadyForDefense,
                                                adapter,
                                                stip_traversal_context_intro);
    slice_index const deadend = branch_find_slice(STDeadEnd,
                                                  ready,
                                                  stip_traversal_context_defense);
    slice_index const proxy1 = alloc_proxy_slice();
    slice_index const proxy2 = alloc_proxy_slice();
    slice_index const dummy = alloc_pipe(STDummyMove);
    slice_index const played = alloc_defense_played_slice();
    slice_index const condition = alloc_goal_check_reached_tester_slice(goal_applies_to_starter);
    slice_index const jump = alloc_if_then_else_slice(proxy1,proxy2,condition);
    slice_index const landing_proto = alloc_pipe(STCheckZigzagLanding);

    assert(ready!=no_slice);
    assert(deadend!=no_slice);
    pipe_link(condition,alloc_true_slice());
    defense_branch_insert_slices(ready,&landing_proto,1);
    pipe_link(proxy2,SLICE_NEXT1(deadend));
    /* the dummy move is needed to make sure that the killer move mechanism
     * applies to the same play whether the attacker has delivered check or not
     * TODO only insert the dummy move if the killer move optimisation is used
     */
    pipe_link(proxy1,dummy);
    pipe_link(dummy,played);
    pipe_link(deadend,jump);

    {
      slice_index const landing = branch_find_slice(STCheckZigzagLanding,
                                                    deadend,
                                                    stip_traversal_context_defense);
      assert(landing!=no_slice);
      link_to_branch(played,landing);
    }
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#23
0
/* Produce slices representing set play.
 * @param adapter identifies the adapter slice at the beginning of the branch
 * @param state address of structure holding state
 */
void help_branch_make_setplay(slice_index adapter, spin_off_state_type *state)
{
  stip_length_type const length = SLICE_U(adapter).branch.length;
  stip_length_type min_length = SLICE_U(adapter).branch.min_length;

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",adapter);
  TraceFunctionParamListEnd();

  assert(SLICE_TYPE(adapter)==STHelpAdapter);

  if (min_length==0)
    min_length = 2;

  if (length>1)
  {
    slice_index const next = SLICE_NEXT1(adapter);
    slice_index const prototypes[] =
    {
      alloc_help_adapter_slice(length-1,min_length-1),
      alloc_pipe(STEndOfRoot)
    };
    enum
    {
      nr_prototypes = sizeof prototypes / sizeof prototypes[0]
    };
    help_branch_insert_slices(next,prototypes,nr_prototypes);

    {
      slice_index const set_adapter = branch_find_slice(STHelpAdapter,
                                                        next,
                                                        stip_traversal_context_help);
      assert(set_adapter!=no_slice);
      help_branch_make_root_slices(set_adapter,state);
      state->spun_off[adapter] = state->spun_off[set_adapter];
      pipe_remove(set_adapter);
    }
  }

  TraceValue("%u\n",state->spun_off[adapter]);

  TraceFunctionExit(__func__);
  TraceFunctionParamListEnd();
}
示例#24
0
static void instrument_doublestalemate_tester(slice_index si,
                                              stip_structure_traversal *st)
{
  in_branch_insertion_state_type * const state = st->param;

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  stip_traverse_structure_children(si,st);

  if (state->in_goal_tester==goal_dblstale)
  {
    slice_index const prototype = alloc_selfcheck_guard_slice();
    /* no need to instrument the operand that tests for stalemate of the
     * starting side */
    goal_branch_insert_slices(SLICE_NEXT1(si),&prototype,1);
    state->is_branch_instrumented = true;
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#25
0
/* Shorten a help branch by 1 half move
 * @param identifies entry slice of branch to be shortened
 */
void help_branch_shorten(slice_index adapter)
{
  slice_index const next = SLICE_NEXT1(adapter);

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",adapter);
  TraceFunctionParamListEnd();

  assert(SLICE_TYPE(adapter)==STHelpAdapter);

  {
    /* find the new spot for adapter by inserting a copy */
    slice_index const prototype = copy_slice(adapter);
    help_branch_insert_slices(next,&prototype,1);
  }

  {
    /* move adapter to its new spot */
    slice_index const copy = branch_find_slice(STHelpAdapter,
                                               next,
                                               stip_traversal_context_help);
    assert(copy!=no_slice);
    pipe_link(SLICE_PREV(adapter),next);
    pipe_append(copy,adapter);
    pipe_remove(copy);
  }

  /* adjust the length and min_length members */
  --SLICE_U(adapter).branch.length;
  if (SLICE_U(adapter).branch.min_length<=0)
    increase_min_length(adapter);
  --SLICE_U(adapter).branch.min_length;
  branch_shorten_slices(next,STHelpAdapter,stip_traversal_context_help);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#26
0
文件: fork.c 项目: Die9teWoge/popeye
/* Detect starter field with the starting side if possible.
 * @param si identifies slice being traversed
 * @param st status of traversal
 */
void fork_detect_starter(slice_index si, stip_structure_traversal *st)
{
  slice_index const fork = SLICE_NEXT2(si);

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  stip_traverse_structure_next_branch(si,st);

  if (SLICE_STARTER(si)==no_side)
  {
    if (SLICE_STARTER(fork)==no_side)
    {
      stip_traverse_structure_children_pipe(si,st);
      SLICE_STARTER(si) = SLICE_STARTER(SLICE_NEXT1(si));
    }
    else
      SLICE_STARTER(si) = SLICE_STARTER(fork);
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
示例#27
0
/* Parse a stipulation expression
 * @param tok input token
 * @param start index of entry into solving machinery
 * @param proxy index of expression slice; no_slice if expression
 *              can't be parsed
 * @param level nesting level of the operand (0 means top level)
 * @return remainder of input token; 0 if parsing failed
 */
static char *ParseStructuredStip_expression(char *tok,
                                            slice_index start,
                                            slice_index proxy,
                                            expression_type *type,
                                            unsigned int level)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%s",tok);
  TraceFunctionParam("%u",start);
  TraceFunctionParam("%u",proxy);
  TraceFunctionParam("%u",level);
  TraceFunctionParamListEnd();

  {
    slice_index const operand1 = alloc_proxy_slice();
    tok = ParseStructuredStip_operand(tok,start,operand1,type,level);
    if (tok!=0 && SLICE_NEXT1(operand1)!=no_slice)
    {
      slice_type operator_type;
      tok = ParseStructuredStip_operator(tok,&operator_type);
      if (tok!=0 && operator_type!=no_slice_type)
      {
        if (*type==expression_type_defense)
          tok = 0;
        else
        {
          slice_index const operand2 = alloc_proxy_slice();
          expression_type type2;
          tok = ParseStructuredStip_expression(tok,start,operand2,&type2,level);
          if (tok!=0 && SLICE_NEXT1(operand2)!=no_slice)
          {
            if (*type==type2)
              switch (operator_type)
              {
                case STAnd:
                {
                  slice_index const and = alloc_and_slice(operand1,operand2);
                  pipe_link(proxy,and);
                  break;
                }

                case STOr:
                {
                  slice_index const or = alloc_or_slice(operand1,operand2);
                  pipe_link(proxy,or);
                  break;
                }

                default:
                  assert(0);
                  break;
              }
            else
              tok = 0;
          }
        }
      }
      else
      {
        if (SLICE_PREV(SLICE_NEXT1(operand1))==operand1)
          pipe_link(proxy,SLICE_NEXT1(operand1));
        else
          pipe_set_successor(proxy,SLICE_NEXT1(operand1));

        dealloc_slice(operand1);
      }
    }
  }

  TraceFunctionExit(__func__);
  TraceFunctionResult("%s",tok);
  TraceFunctionResultEnd();
  return tok;
}
示例#28
0
static char *ParsePlay(char *tok,
                       slice_index start,
                       slice_index proxy,
                       play_length_type play_length)
{
    /* seriesmovers with introductory moves */
    char *result = 0;
    char *arrowpos;
    slice_index const proxy_next = alloc_proxy_slice();

    TraceFunctionEntry(__func__);
    TraceFunctionParam("%s",tok);
    TraceFunctionParam("%u",start);
    TraceFunctionParam("%u",proxy);
    TraceFunctionParamListEnd();

    if (token_starts_with("exact-",tok))
    {
        play_length = play_length_exact;
        tok += 6;
    }

    arrowpos = strstr(tok,"->");
    if (arrowpos!=0)
    {
        char *end;
        unsigned long const intro_len= strtoul(tok,&end,10);
        if (intro_len<1 || tok==end || end!=arrowpos)
            output_plaintext_input_error_message(WrongInt, 0);
        else
        {
            result = ParsePlay(arrowpos+2,start,proxy_next,play_length);
            if (result!=0 && SLICE_NEXT1(proxy_next)!=no_slice)
            {
                /* >=1 move of starting side required */
                slice_index const branch = alloc_series_branch(2*intro_len-1,1);
                help_branch_set_end(branch,proxy_next,1);
                link_to_branch(proxy,branch);
                select_output_mode(proxy,output_mode_line);
            }
        }
    }

    else if (token_starts_with("ser-reci-h",tok))
    {
        /* skip over "ser-reci-h" */
        tok = ParseReciEnd(tok+10,start,proxy_next);
        if (tok!=0 && SLICE_NEXT1(proxy_next)!=no_slice)
        {
            stip_length_type length;
            stip_length_type min_length;
            result = ParseSeriesLength(tok,&length,&min_length,play_length);
            if (result!=0)
            {
                slice_index const branch = alloc_series_branch(length-1,min_length+1);
                help_branch_set_end(branch,proxy_next,1);
                link_to_branch(proxy,branch);

                solving_impose_starter(proxy_next,Black);
                select_output_mode(proxy,output_mode_line);
            }
        }
    }

    else if (token_starts_with("ser-hs",tok))
    {
        tok = ParseGoal(tok+6,start,proxy_next); /* skip over "ser-hs" */
        if (tok!=0)
        {
            stip_length_type length;
            stip_length_type min_length;
            result = ParseSeriesLength(tok,&length,&min_length,play_length);
            if (result!=0)
            {
                slice_index const defense_branch = MakeEndOfSelfPlay(proxy_next);

                /* in ser-hs, the series is 1 half-move longer than in usual
                 * series play! */
                if (length==0)
                    pipe_link(proxy,defense_branch);
                else
                {
                    slice_index const series = alloc_series_branch(length,min_length);

                    slice_index const help_proxy = alloc_proxy_slice();
                    slice_index const help = alloc_help_branch(1,1);
                    link_to_branch(help_proxy,help);
                    help_branch_set_end_forced(help_proxy,defense_branch,1);
                    help_branch_set_end(series,help_proxy,1);
                    link_to_branch(proxy,series);
                }

                solving_impose_starter(proxy_next,White);
                select_output_mode(proxy,output_mode_line);
            }
        }
    }

    else if (token_starts_with("ser-h",tok))
    {
        result = ParseSeries(tok+5,start,proxy,proxy_next,play_length); /* skip over "ser-h" */
        if (result!=0)
        {
            slice_index const help = alloc_help_branch(1,1);
            help_branch_set_end_goal(help,proxy_next,1);
            help_branch_set_end(proxy,help,1);

            {
                slice_index const next = SLICE_NEXT1(proxy_next);
                assert(next!=no_slice);
                if (SLICE_TYPE(next)==STGoalReachedTester
                        && SLICE_U(next).goal_handler.goal.type==goal_proofgame)
                    solving_impose_starter(proxy_next,White);
                else
                    solving_impose_starter(proxy_next,Black);
            }
        }
    }

    else if (token_starts_with("ser-s",tok))
    {
        result = ParseSeries(tok+5,start,proxy,proxy_next,play_length); /* skip over "ser-s" */
        if (result!=0)
        {
            help_branch_set_end_forced(proxy,MakeEndOfSelfPlay(proxy_next),1);
            solving_impose_starter(proxy_next,White);
        }
    }

    else if (token_starts_with("ser-r",tok))
    {
        result = ParseSeries(tok+5,start,proxy,proxy_next,play_length); /* skip over "ser-r" */
        if (result!=0)
        {
            slice_index const proxy_semi = MakeSemireflexBranch(proxy_next);
            help_branch_set_end_forced(proxy,proxy_semi,1);
            series_branch_insert_constraint(proxy,MakeReflexBranch(proxy_semi));
            solving_impose_starter(proxy_next,White);
        }
    }

    else if (token_starts_with("ser-",tok))
    {
        result = ParseSeries(tok+4,start,proxy,proxy_next,play_length); /* skip over "ser-" */
        if (result!=0)
        {
            help_branch_set_end_goal(proxy,proxy_next,1);
            solving_impose_starter(proxy_next,Black);
        }
    }

    else if (token_starts_with("phser-r",tok))
    {
        boolean const shorten = true;
        result = ParseHelp(tok+7, /* skip over phser-r */
                           start,
                           proxy,proxy_next,
                           play_length,shorten);
        if (result!=0)
        {
            slice_index const proxy_semi = MakeSemireflexBranch(proxy_next);
            help_branch_set_end_forced(proxy,proxy_semi,1);
            if (help_branch_insert_constraint(proxy,MakeReflexBranch(proxy_semi),0))
            {
                help_branch_insert_check_zigzag(proxy);
                solving_impose_starter(proxy_next,White);
            }
            else
                result = 0;
        }
    }

    else if (token_starts_with("phser-s",tok))
    {
        boolean const shorten = true;
        result = ParseHelp(tok+7, /* skip over phser-s */
                           start,
                           proxy,proxy_next,
                           play_length,shorten);
        if (result!=0)
        {
            help_branch_set_end_forced(proxy,MakeEndOfSelfPlay(proxy_next),1);
            help_branch_insert_check_zigzag(proxy);
            solving_impose_starter(proxy_next,White);
        }
    }

    else if (token_starts_with("phser-",tok))
    {
        boolean const shorten = true;
        result = ParseHelp(tok+6, /* skip over phser- */
                           start,
                           proxy,proxy_next,
                           play_length,shorten);
        if (result!=0)
        {
            help_branch_set_end_goal(proxy,proxy_next,1);
            help_branch_insert_check_zigzag(proxy);
            solving_impose_starter(proxy_next,Black);
        }
    }

    else if (token_starts_with("pser-hs",tok))
    {
        tok = ParseGoal(tok+7,start,proxy_next); /* skip over "ser-hs" */
        if (tok!=0)
        {
            stip_length_type length;
            stip_length_type min_length;
            result = ParseSeriesLength(tok,&length,&min_length,play_length);
            if (result!=0)
            {
                slice_index const series = alloc_help_branch(length,min_length);
                slice_index const help_proxy = alloc_proxy_slice();
                slice_index const help = alloc_help_branch(1,1);
                slice_index const defense_branch = MakeEndOfSelfPlay(proxy_next);
                link_to_branch(help_proxy,help);
                help_branch_set_end_forced(help_proxy,defense_branch,1);
                help_branch_set_end(series,help_proxy,1);
                link_to_branch(proxy,series);
                help_branch_insert_check_zigzag(proxy);
                solving_impose_starter(proxy_next,White);
                select_output_mode(proxy,output_mode_line);
            }
        }
    }

    else if (token_starts_with("pser-h",tok))
    {
        boolean const shorten = true;
        result = ParseHelp(tok+6, /* skip over pser-h */
                           start,
                           proxy,proxy_next,
                           play_length,shorten);
        if (result!=0)
        {
            slice_index const to_goal = SLICE_NEXT1(proxy_next);
            slice_index const nested = alloc_help_branch(1,1);
            help_branch_set_end_goal(nested,proxy_next,1);
            help_branch_set_end(proxy,nested,1);
            help_branch_insert_check_zigzag(proxy);
            if (SLICE_TYPE(to_goal)==STGoalReachedTester
                    && SLICE_U(to_goal).goal_handler.goal.type==goal_proofgame)
                solving_impose_starter(proxy_next,White);
            else
                solving_impose_starter(proxy_next,Black);
        }
    }

    else if (token_starts_with("pser-r",tok))
    {
        boolean const ends_on_defense = false;
        result = ParseBattle(tok+6, /* skip over pser-r */
                             start,
                             proxy,proxy_next,
                             play_length,ends_on_defense);
        if (result!=0)
        {
            slice_index const proxy_semi = MakeSemireflexBranch(proxy_next);
            battle_branch_insert_end_of_branch_forced(proxy,proxy_semi);
            battle_branch_insert_attack_constraint(proxy,MakeReflexBranch(proxy_semi));
            battle_branch_insert_defense_check_zigzag(proxy);
            select_output_mode(proxy,output_mode_line);
            solving_impose_starter(proxy_next,White);
        }
    }

    else if (token_starts_with("pser-s",tok))
    {
        boolean const ends_on_defense = false;
        result = ParseBattle(tok+6, /* skip over pser-s */
                             start,
                             proxy,proxy_next,
                             play_length,ends_on_defense);
        if (result!=0)
        {
            battle_branch_insert_direct_end_of_branch(proxy,
                    MakeEndOfSelfPlay(proxy_next));
            solving_impose_starter(proxy_next,Black);
            select_output_mode(proxy,output_mode_line);
            battle_branch_insert_defense_check_zigzag(proxy);
        }
    }

    else if (token_starts_with("pser-",tok))
    {
        boolean const ends_on_defense = false;
        result = ParseBattle(tok+5, /* skip over pser- */
                             start,
                             proxy,proxy_next,
                             play_length,ends_on_defense);
        if (result!=0)
        {
            select_output_mode(proxy,output_mode_line);
            battle_branch_insert_direct_end_of_branch_goal(proxy,proxy_next);
            battle_branch_insert_defense_check_zigzag(proxy);
        }
    }

    else if (token_starts_with("reci-h",tok))
    {
        char * const tok2 = ParseReciEnd(tok+6, /* skip over "reci-h" */
                                         start,proxy_next);
        if (tok2!=0 && SLICE_NEXT1(proxy_next)!=no_slice)
        {
            stip_length_type length;
            stip_length_type min_length;
            result = ParseHelpLength(tok2,&length,&min_length,play_length);

            if (length==1)
            {
                /* at least 2 half moves requried for a reciprocal stipulation */
                output_plaintext_input_error_message(StipNotSupported,0);
                result = 0;
            }

            if (result!=0)
            {
                if (length==2)
                {
                    pipe_link(proxy,SLICE_NEXT1(proxy_next));
                    dealloc_slice(proxy_next);
                }
                else
                {
                    stip_length_type const min_length2 = (min_length<2
                                                          ? min_length
                                                          : min_length-2);
                    slice_index const branch = alloc_help_branch(length-2,min_length2);
                    help_branch_set_end(branch,proxy_next,1);
                    attach_help_branch(length,proxy,branch);
                }

                solving_impose_starter(proxy_next,Black);
                select_output_mode(proxy,output_mode_line);
            }
        }
    }

    else if (token_starts_with("dia",tok))
    {
        result = ParseHelpDia(tok,start,proxy,proxy_next,play_length);
        if (result!=0)
            solving_impose_starter(proxy,White);
    }
    else if (token_starts_with("a=>b",tok))
    {
        result = ParseHelpDia(tok,start,proxy,proxy_next,play_length);
        if (result!=0)
            solving_impose_starter(proxy,Black);
    }

    else if (token_starts_with("hs",tok))
    {
        boolean const shorten = true;
        result = ParseHelp(tok+2, /* skip over "hs" */
                           start,
                           proxy,proxy_next,
                           play_length,shorten);
        if (result!=0)
        {
            help_branch_set_end_forced(proxy,MakeEndOfSelfPlay(proxy_next),1);
            solving_impose_starter(proxy_next,White);
        }
    }

    else if (token_starts_with("hr",tok))
    {
        boolean const shorten = true;
        result = ParseHelp(tok+2, /* skip over "hr" */
                           start,
                           proxy,proxy_next,
                           play_length,shorten);
        if (result!=0)
        {
            slice_index const proxy_semi = MakeSemireflexBranch(proxy_next);
            help_branch_set_end_forced(proxy,proxy_semi,1);
            if (help_branch_insert_constraint(proxy,MakeReflexBranch(proxy_semi),0))
                solving_impose_starter(proxy_next,White);
            else
                result = 0;
        }
    }

    else if (token_starts_with("h",tok))
    {
        boolean const shorten = false;
        result = ParseHelp(tok+1, /* skip over "h" */
                           start,
                           proxy,proxy_next,
                           play_length,shorten);
        if (result!=0)
        {
            help_branch_set_end_goal(proxy,proxy_next,1);
            solving_impose_starter(proxy_next,Black);
        }
    }

    else if (token_starts_with("semi-r",tok))
    {
        boolean const ends_on_defense = false;
        result = ParseBattle(tok+6, /* skip over "semi-r" */
                             start,
                             proxy,proxy_next,
                             play_length,ends_on_defense);
        if (result!=0)
        {
            battle_branch_insert_end_of_branch_forced(proxy,
                    MakeSemireflexBranch(proxy_next));
            select_output_mode(proxy,output_mode_tree);
            solving_impose_starter(proxy_next,White);
        }
    }

    else if (token_starts_with("s",tok))
    {
        boolean const ends_on_defense = true;
        result = ParseBattle(tok+1, /* skip over 's' */
                             start,
                             proxy,proxy_next,
                             play_length,ends_on_defense);
        if (result!=0)
        {
            select_output_mode(proxy,output_mode_tree);
            battle_branch_insert_self_end_of_branch_goal(proxy,proxy_next);
        }
    }

    else if (token_starts_with("r",tok))
    {
        boolean const ends_on_defense = false;
        result = ParseBattle(tok+1, /* skip over 'r' */
                             start,
                             proxy,proxy_next,
                             play_length,ends_on_defense);
        if (result!=0)
        {
            slice_index const proxy_semi = MakeSemireflexBranch(proxy_next);
            battle_branch_insert_end_of_branch_forced(proxy,proxy_semi);
            battle_branch_insert_attack_constraint(proxy,MakeReflexBranch(proxy_semi));
            select_output_mode(proxy,output_mode_tree);
            solving_impose_starter(proxy_next,White);
        }
    }

    else
    {
        boolean const ends_on_defense = false;
        result = ParseBattle(tok,start,proxy,proxy_next,play_length,ends_on_defense);
        if (result!=0)
        {
            select_output_mode(proxy,output_mode_tree);
            battle_branch_insert_direct_end_of_branch_goal(proxy,proxy_next);
        }
    }

    if (result==0)
        dealloc_slices(proxy_next);

    TraceFunctionExit(__func__);
    TraceFunctionResult("%s",result);
    TraceFunctionResultEnd();
    return result;
}
示例#29
0
static void spin_off_measuring_branch(slice_index si, stip_structure_traversal *st)
{
  instrumentation_state_type const * const state = st->param;

  stip_deep_copies_type copies;
  stip_structure_traversal st_nested;

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  if (SLICE_NEXT2(si)==no_slice)
  {
    SLICE_NEXT2(si) = alloc_proxy_slice();

    init_deep_copy(&st_nested,st,&copies);
    stip_structure_traversal_override_single(&st_nested,
                                             STMummerDeadend,
                                             &stop_copying);
    stip_structure_traversal_override_single(&st_nested,
                                             STRestartGuard,
                                             &skip_copying);
    stip_structure_traversal_override_single(&st_nested,
                                             STDeadEndGoal,
                                             &skip_copying);
    stip_structure_traversal_override_single(&st_nested,
                                             STGoalReachableGuardFilterMate,
                                             &skip_copying);
    stip_structure_traversal_override_single(&st_nested,
                                             STGoalReachableGuardFilterStalemate,
                                             &skip_copying);
    stip_structure_traversal_override_single(&st_nested,
                                             STGoalReachableGuardFilterProof,
                                             &skip_copying);
    stip_structure_traversal_override_single(&st_nested,
                                             STGoalReachableGuardFilterProofFairy,
                                             &skip_copying);
    stip_structure_traversal_override_by_function(&st_nested,
                                                  slice_function_move_removing_optimiser,
                                                  &skip_copying);
    if (mummer_strictness[state->current_side]!=mummer_strictness_regular)
    {
      stip_structure_traversal_override_single(&st_nested,
                                               STEndOfBranchGoal,
                                               &skip_copying);
      stip_structure_traversal_override_single(&st_nested,
                                               STSelfCheckGuard,
                                               &skip_copying);
    }
    else
    {
      regular_deep_copy_end_of_branch_goal = st_nested.map.visitors[STEndOfBranchGoal];
      stip_structure_traversal_override_single(&st_nested,
                                               STEndOfBranchGoal,
                                               &copy_end_of_branch_goal_if_necessary);
      stip_structure_traversal_override_single(&st_nested,
                                               STEndOfBranchGoalImmobile,
                                               &copy_end_of_branch_goal_if_necessary);
    }

    stip_traverse_structure(SLICE_NEXT1(si),&st_nested);

    link_to_branch(SLICE_NEXT2(si),copies[SLICE_NEXT1(si)]);

    {
      slice_index const prototype = alloc_pipe(STMummerBookkeeper);
      switch (st->context)
      {
        case stip_traversal_context_attack:
          attack_branch_insert_slices_behind_proxy(SLICE_NEXT2(si),&prototype,1,si);
          break;

        case stip_traversal_context_defense:
          defense_branch_insert_slices_behind_proxy(SLICE_NEXT2(si),&prototype,1,si);
          break;

        case stip_traversal_context_help:
          help_branch_insert_slices_behind_proxy(SLICE_NEXT2(si),&prototype,1,si);
          break;

        default:
          assert(0);
          break;
      }
    }

    if (mummer_strictness[state->current_side]!=mummer_strictness_regular)
    {
      slice_index const prototype = alloc_pipe(STUltraMummerMeasurerDeadend);
      slice_insertion_insert_contextually(copies[SLICE_NEXT1(si)],st->context,&prototype,1);
    }
  }

  stip_traverse_structure_children(si,st);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}