Ejemplo n.º 1
0
/* Insert slices into a battle branch; the elements of
 * prototypes are *not* deallocated by battle_branch_insert_slices_nested().
 * The inserted slices are copies of the elements of prototypes).
 * Each slice is inserted at a position that corresponds to its predefined rank.
 * @param adapter identifies starting point of insertion (of type STAttackAdapter
 *                or STDefenseAdapter)
 * @param prototypes contains the prototypes whose copies are inserted
 * @param nr_prototypes number of elements of array prototypes
 */
void battle_branch_insert_slices_nested(slice_index adapter,
                                        slice_index const prototypes[],
                                        unsigned int nr_prototypes)
{
  stip_structure_traversal st;
  branch_slice_insertion_state_type state =
  {
    prototypes, nr_prototypes,
    slice_rank_order, nr_slice_rank_order_elmts, 0,
    branch_slice_rank_order_recursive,
    0,
    adapter,
    0
  };

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

  assert(SLICE_TYPE(adapter)==STAttackAdapter
         || SLICE_TYPE(adapter)==STDefenseAdapter);

  state.base_rank = get_slice_rank(SLICE_TYPE(adapter),&state);
  assert(state.base_rank!=no_slice_rank);
  slice_insertion_init_traversal(&st,&state,stip_traversal_context_intro);
  move_init_slice_insertion_traversal(&st);
  stip_traverse_structure_children_pipe(adapter,&st);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Ejemplo n.º 2
0
/* (Approximately) depth-first traversl of the stipulation
 * @param root start of the stipulation (sub)tree
 * @param st address of data structure holding parameters for the operation
 */
void stip_traverse_moves(slice_index root, stip_moves_traversal *st)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",root);
  TraceFunctionParam("%p",st);
  TraceFunctionParamListEnd();

  TraceValue("%u",st->remaining);
  TraceEOL();

  TraceEnumerator(slice_type,SLICE_TYPE(root));
  TraceEOL();
  assert(SLICE_TYPE(root)<=nr_slice_types);

  if (st->remaining_watermark[root]<=st->remaining)
  {
    stip_moves_visitor const operation = st->map.visitors[SLICE_TYPE(root)];
    assert(operation!=0);
    (*operation)(root,st);
    st->remaining_watermark[root] = st->remaining+1;
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Ejemplo n.º 3
0
static void move_generation_branch_insert_slices_impl(slice_index generating,
                                                      slice_index const prototypes[],
                                                      unsigned int nr_prototypes,
                                                      slice_index base)
{
  stip_structure_traversal st;
  branch_slice_insertion_state_type state =
  {
    prototypes,nr_prototypes,
    slice_rank_order, nr_slice_rank_order_elmts, 1,
    branch_slice_rank_order_nonrecursive,
    0,
    generating,
    0
  };

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

  state.base_rank = get_slice_rank(SLICE_TYPE(base),&state);
  assert(state.base_rank!=no_slice_rank);

  slice_insertion_init_traversal(&st,&state,stip_traversal_context_intro);
  circe_init_slice_insertion_traversal(&st);

  stip_traverse_structure(generating,&st);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Ejemplo n.º 4
0
static void help_branch_insert_slices_impl(slice_index si,
                                           slice_index const prototypes[],
                                           unsigned int nr_prototypes,
                                           slice_index base)
{
  stip_structure_traversal st;
  branch_slice_insertion_state_type state =
  {
      prototypes, nr_prototypes,
      slice_rank_order, nr_slice_rank_order_elmts, 0,
      branch_slice_rank_order_recursive,
      0,
      si,
      0
  };

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

  slice_insertion_init_traversal(&st,&state,stip_traversal_context_help);
  move_init_slice_insertion_traversal(&st);

  state.base_rank = get_slice_rank(SLICE_TYPE(base),&state);

  stip_traverse_structure(si,&st);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Ejemplo n.º 5
0
/* Like attack_branch_insert_slices, but starting at a proxy slice
 * @param base used instead of proxy for determining the current position in the
 *             sequence of defense branches
 */
void attack_branch_insert_slices_behind_proxy(slice_index proxy,
                                              slice_index const prototypes[],
                                              unsigned int nr_prototypes,
                                              slice_index base)
{
  stip_structure_traversal st;
  branch_slice_insertion_state_type state =
  {
    prototypes, nr_prototypes,
    slice_rank_order, nr_slice_rank_order_elmts, 0,
    branch_slice_rank_order_recursive,
    0,
    proxy,
    0
  };

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",proxy);
  TraceFunctionParam("%u",nr_prototypes);
  TraceFunctionParamListEnd();

  assert(SLICE_TYPE(proxy)!=STAttackPlayed);

  state.base_rank = get_slice_rank(STAttackPlayed,&state);
  assert(state.base_rank!=no_slice_rank);
  ++state.base_rank;

  state.base_rank = get_slice_rank(STDefensePlayed,&state);
  assert(state.base_rank!=no_slice_rank);
  ++state.base_rank;

  slice_insertion_init_traversal(&st,&state,stip_traversal_context_attack);
  move_init_slice_insertion_traversal(&st);

  state.base_rank = get_slice_rank(SLICE_TYPE(base),&state);
  stip_traverse_structure(proxy,&st);

  deallocate_slice_insertion_prototypes(prototypes,nr_prototypes);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Ejemplo n.º 6
0
/* (Approximately) depth-first traversl of a stipulation sub-tree
 * @param root root of the sub-tree to traverse
 * @param st address of structure defining traversal
 */
void stip_traverse_moves_children(slice_index si,
                                  stip_moves_traversal *st)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  TraceEnumerator(slice_type,SLICE_TYPE(si));
  TraceEOL();
  assert(SLICE_TYPE(si)<=nr_slice_types);

  {
    slice_type const type = SLICE_TYPE(si);
    stip_moves_visitor const operation = moves_children_traversers.visitors[type];
    assert(operation!=0);
    (*operation)(si,st);
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Ejemplo n.º 7
0
static void insert_enforcers(slice_index si, stip_structure_traversal *st)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParamListEnd();

  stip_traverse_structure_children(si,st);

  {
    stip_deep_copies_type copies;
    stip_structure_traversal st_nested;

    slice_index const * const threat_start = st->param;
    slice_index const threat_start_tester = SLICE_TESTER(*threat_start);

    assert(*threat_start!=no_slice);
    assert(threat_start_tester!=no_slice);
    assert(SLICE_TYPE(threat_start_tester)==STThreatStart);

    {
      slice_index const prototype = alloc_pipe(STThreatDefeatedTester);
      attack_branch_insert_slices(threat_start_tester,&prototype,1);
    }

    init_deep_copy(&st_nested,st,&copies);
    stip_structure_traversal_override_single(&st_nested,
                                             STThreatDefeatedTester,
                                             &move_and_stop_copying);
    stip_structure_traversal_override_by_contextual(&st_nested,
                                                    slice_contextual_conditional_pipe,
                                                    &copy_shallow);
    stip_structure_traversal_override_by_contextual(&st_nested,
                                                    slice_contextual_testing_pipe,
                                                    &copy_shallow);
    stip_traverse_structure(threat_start_tester,&st_nested);

    SLICE_NEXT2(si) = copies[threat_start_tester];
  }

  {
    /* if the threats are short, max_unsolvable might interfere with enforcing
     * them */
    slice_index const prototype = alloc_reset_unsolvable_slice();
    attack_branch_insert_slices(SLICE_NEXT2(si),&prototype,1);
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Ejemplo n.º 8
0
/* Insert slices into a help branch; the elements of
 * prototypes are *not* deallocated by help_branch_insert_slices_nested().
 * The inserted slices are copies of the elements of prototypes).
 * Each slice is inserted at a position that corresponds to its predefined rank.
 * @param adapter identifies starting point of insertion (of type STHelpAdapter)
 * @param prototypes contains the prototypes whose copies are inserted
 * @param nr_prototypes number of elements of array prototypes
 */
void help_branch_insert_slices_nested(slice_index adapter,
                                      slice_index const prototypes[],
                                      unsigned int nr_prototypes)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",adapter);
  TraceFunctionParam("%u",nr_prototypes);
  TraceFunctionParamListEnd();

  assert(SLICE_TYPE(adapter)==STHelpAdapter);
  help_branch_insert_slices_impl(adapter,prototypes,nr_prototypes,adapter);

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Ejemplo n.º 9
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();
}
Ejemplo n.º 10
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();
}
Ejemplo n.º 11
0
/* Wrap the slices representing the initial moves of the solution with
 * slices of appropriately equipped slice types
 * @param adapter identifies the adapter slice at the beginning of the branch
 * @param state address of structure holding state
 */
void help_make_root(slice_index adapter, spin_off_state_type *state)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",adapter);
  TraceFunctionParamListEnd();

  assert(SLICE_TYPE(adapter)==STHelpAdapter);

  {
    slice_index const prototype = alloc_pipe(STEndOfRoot);
    slice_insertion_insert(adapter,&prototype,1);
    help_branch_make_root_slices(adapter,state);
    branch_shorten_slices(adapter,STEndOfRoot,stip_traversal_context_intro);
    pipe_remove(adapter);
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Ejemplo n.º 12
0
static void stip_traverse_moves_conditional_pipe_tester(slice_index conditional_pipe,
                                                        stip_moves_traversal *st)
{
  stip_traversal_activity_type const save_activity = st->activity;

  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",conditional_pipe);
  TraceFunctionParam("%p",st);
  TraceFunctionParamListEnd();

  assert(slice_type_get_contextual_type(SLICE_TYPE(conditional_pipe))
         ==slice_contextual_conditional_pipe);

  st->activity = stip_traversal_activity_testing;
  stip_traverse_moves_branch(SLICE_NEXT2(conditional_pipe),st);
  st->activity = save_activity;

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Ejemplo n.º 13
0
/* Instrument a series branch with STConstraintTester slices (as possible in
 * elabore sstip stipulations)
 * @param si entry slice of branch to be instrumented
 * @param constraint identifies branch that constrains the attacker
 */
void series_branch_insert_goal_constraint(slice_index si, slice_index constraint)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",si);
  TraceFunctionParam("%u",constraint);
  TraceFunctionParamListEnd();

  TraceStipulation(si);
  TraceStipulation(constraint);

  assert(SLICE_TYPE(constraint)==STProxy);

  {
    slice_index const prototype = alloc_goal_constraint_tester_slice(constraint);
    slice_insertion_insert(si,&prototype,1);
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Ejemplo n.º 14
0
static void stip_traverse_moves_testing_pipe_tester(slice_index testing_pipe,
                                                    stip_moves_traversal *st)
{
  TraceFunctionEntry(__func__);
  TraceFunctionParam("%u",testing_pipe);
  TraceFunctionParamListEnd();

  assert(slice_type_get_contextual_type(SLICE_TYPE(testing_pipe))
         ==slice_contextual_testing_pipe);

  if (SLICE_NEXT2(testing_pipe)!=no_slice)
  {
    stip_traversal_activity_type const save_activity = st->activity;
    st->activity = stip_traversal_activity_testing;
    stip_traverse_moves(SLICE_NEXT2(testing_pipe),st);
    st->activity = save_activity;
  }

  TraceFunctionExit(__func__);
  TraceFunctionResultEnd();
}
Ejemplo n.º 15
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();
}
Ejemplo n.º 16
0
/* Make the postkey play representation of a non-postkey play representation
 * @param adapter identifies adapter slice into battle branch
 * @return identifier to adapter slice into postkey representation
 */
slice_index battle_branch_make_postkeyplay(slice_index adapter)
{
  slice_index result;

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

  TraceStipulation(adapter);

  assert(SLICE_TYPE(adapter)==STAttackAdapter);

  {
    slice_index const notend = branch_find_slice(STNotEndOfBranchGoal,
                                                 adapter,
                                                 stip_traversal_context_intro);
    stip_length_type const length = SLICE_U(adapter).branch.length;
    stip_length_type const min_length = SLICE_U(adapter).branch.min_length;
    slice_index const proto = alloc_defense_adapter_slice(length-1,
                                                          min_length-1);
    assert(notend!=no_slice);
    defense_branch_insert_slices(notend,&proto,1);

    result = branch_find_slice(STDefenseAdapter,
                               notend,
                               stip_traversal_context_defense);
    assert(result!=no_slice);

    branch_shorten_slices(adapter,STDefenseAdapter,stip_traversal_context_intro);
    pipe_remove(adapter);
  }

  TraceFunctionExit(__func__);
  TraceFunctionParam("%u",result);
  TraceFunctionParamListEnd();
  return result;
}
Ejemplo n.º 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();
}
Ejemplo n.º 18
0
void parse_slice_header(decoder_context *decoder)
{
	bitstream_reader *reader = &decoder->reader;
	decoder_context_sps *sps;
	decoder_context_pps *pps;
	unsigned pps_id;
	int i;

	decoder_reset_SH(decoder);

	decoder->sh.first_mb_in_slice = bitstream_read_ue(reader);
	decoder->sh.slice_type = bitstream_read_ue(reader);
	pps_id = bitstream_read_ue(reader);

	SYNTAX_IPRINT("first_mb_in_slice = %u\n", decoder->sh.first_mb_in_slice);
	SYNTAX_IPRINT("slice_type %u = \"%s\"\n", decoder->sh.slice_type, SLICE_TYPE(decoder->sh.slice_type));
	SYNTAX_IPRINT("pic_parameter_set_id = %u\n", pps_id);

	if (pps_id > 255) {
		SYNTAX_ERR("Slice header is malformed, pps_id overflow\n");
	}

	if (!decoder->pps[pps_id].valid) {
		SYNTAX_ERR("Cannot parse slice while PPS is invalid\n");
	}

	decoder->active_pps = &decoder->pps[pps_id];
	pps = decoder->active_pps;

	decoder->active_sps = &decoder->sps[pps->seq_parameter_set_id];
	sps = decoder->active_sps;

	decoder->sh.slice_type %= 5;

	if (sps->separate_colour_plane_flag) {
		decoder->sh.colour_plane_id = bitstream_read_u(reader, 2);

		SYNTAX_IPRINT("colour_plane_id = %u\n", decoder->sh.colour_plane_id);
	}

	decoder->sh.frame_num =
		bitstream_read_u(reader, sps->log2_max_frame_num_minus4 + 4);

	SYNTAX_IPRINT("frame_num = %u\n", decoder->sh.frame_num);

	if (!sps->frame_mbs_only_flag) {
		decoder->sh.field_pic_flag = bitstream_read_u(reader, 1);

		SYNTAX_IPRINT("field_pic_flag = %u\n", decoder->sh.field_pic_flag);

		if (decoder->sh.field_pic_flag) {
			decoder->sh.bottom_field_flag = bitstream_read_u(reader, 1);

			SYNTAX_IPRINT("bottom_field_flag = %u\n",
				      decoder->sh.bottom_field_flag);
		}
	}

	if (IdrPicFlag) {
		decoder->sh.idr_pic_id = bitstream_read_ue(reader);

		SYNTAX_IPRINT("idr_pic_id = %u\n", decoder->sh.idr_pic_id);
	}

	if (sps->pic_order_cnt_type == 0) {
		decoder->sh.pic_order_cnt_lsb =
			bitstream_read_u(reader, sps->log2_max_pic_order_cnt_lsb_minus4 + 4 );

		SYNTAX_IPRINT("pic_order_cnt_lsb = %u\n",
			      decoder->sh.pic_order_cnt_lsb);

		if (pps->bottom_field_pic_order_in_frame_present_flag &&
			!decoder->sh.field_pic_flag)
		{
			decoder->sh.delta_pic_order_cnt_bottom = bitstream_read_se(reader);

			SYNTAX_IPRINT("delta_pic_order_cnt_bottom = %d\n",
				      decoder->sh.delta_pic_order_cnt_bottom);
		}
	}

	if (sps->pic_order_cnt_type == 1 &&
		!sps->delta_pic_order_always_zero_flag)
	{
		decoder->sh.delta_pic_order_cnt[0] = bitstream_read_se(reader);

		SYNTAX_IPRINT("delta_pic_order_cnt[0] = %d\n",
			      decoder->sh.delta_pic_order_cnt[0]);

		if (pps->bottom_field_pic_order_in_frame_present_flag &&
			!decoder->sh.field_pic_flag)
		{
			decoder->sh.delta_pic_order_cnt[1] = bitstream_read_se(reader);

			SYNTAX_IPRINT("delta_pic_order_cnt[1] = %d\n",
				      decoder->sh.delta_pic_order_cnt[1]);
		}
	}

	if (pps->redundant_pic_cnt_present_flag) {
		decoder->sh.redundant_pic_cnt = bitstream_read_ue(reader);

		SYNTAX_IPRINT("redundant_pic_cnt = %u\n",
			      decoder->sh.redundant_pic_cnt);
	}

	switch (decoder->sh.slice_type) {
	case B:
		decoder->sh.direct_spatial_mv_pred_flag =
						bitstream_read_u(reader, 1);

		SYNTAX_IPRINT("direct_spatial_mv_pred_flag = %u\n",
			      decoder->sh.direct_spatial_mv_pred_flag);
	case P:
	case SP:
		decoder->sh.num_ref_idx_active_override_flag =
						bitstream_read_u(reader, 1);

		SYNTAX_IPRINT("num_ref_idx_active_override_flag = %u\n",
			      decoder->sh.num_ref_idx_active_override_flag);

		if (!decoder->sh.num_ref_idx_active_override_flag) {
			break;
		}

		decoder->sh.num_ref_idx_l0_active_minus1 =
						bitstream_read_ue(reader);

		SYNTAX_IPRINT("num_ref_idx_l0_active_minus1 = %u\n",
			      decoder->sh.num_ref_idx_l0_active_minus1);

		if (decoder->sh.slice_type != B) {
			break;
		}

		decoder->sh.num_ref_idx_l1_active_minus1 =
						bitstream_read_ue(reader);

		SYNTAX_IPRINT("num_ref_idx_l1_active_minus1 = %u\n",
			      decoder->sh.num_ref_idx_l1_active_minus1);
		break;
	default:
		break;
	}

	// ref_pic_list_modification( )
	{
		unsigned ref_pic_list_modification_flag_l0;
		unsigned ref_pic_list_modification_flag_l1;
		uint32_t modification_of_pic_nums_idc;
		uint32_t abs_diff_pic_num_minus1;
		uint32_t long_term_pic_num;
		int predicted_picture = decoder->sh.frame_num;
		int remapped_picture;
		int refIdxL = 0;
		int l1 = 0;

		switch (decoder->sh.slice_type) {
		case P:
		case B:
		case SP:
			ref_pic_list_modification_flag_l0 = bitstream_read_u(reader, 1);

			SYNTAX_IPRINT("ref_pic_list_modification_flag_l0 = %u\n",
				      ref_pic_list_modification_flag_l0);

			if (!ref_pic_list_modification_flag_l0) {
				goto flag_l1;
			}
pics_num:
			modification_of_pic_nums_idc = bitstream_read_ue(reader);

			SYNTAX_IPRINT("modification_of_pic_nums_idc = %u\n",
				      modification_of_pic_nums_idc);

			switch (modification_of_pic_nums_idc) {
			case 0 ... 1:
				abs_diff_pic_num_minus1 = bitstream_read_ue(reader);

				SYNTAX_IPRINT("abs_diff_pic_num_minus1 = %u\n",
					      abs_diff_pic_num_minus1);

				if (modification_of_pic_nums_idc) {
					remapped_picture = predicted_picture + abs_diff_pic_num_minus1;

					SYNTAX_IPRINT("refIdxL%d <- %d\n", l1, remapped_picture);

					predicted_picture = remapped_picture;
				}
				goto pics_num;
			case 2:
				long_term_pic_num = bitstream_read_ue(reader);

				SYNTAX_IPRINT("long_term_pic_num = %u\n",
					      long_term_pic_num);
				goto pics_num;
			case 3:
				if (l1) {
					break;
				}
flag_l1:
				switch (decoder->sh.slice_type) {
				case B:
				case B_ONLY:
					ref_pic_list_modification_flag_l1 =
							bitstream_read_u(reader, 1);

					SYNTAX_IPRINT("ref_pic_list_modification_flag_l1 = %u\n",
						      ref_pic_list_modification_flag_l1);

					if (!ref_pic_list_modification_flag_l1) {
						break;
					}

					l1 = 1;
					goto pics_num;
				}
				break;
			default:
				SYNTAX_ERR("slice header is malformed\n");
			}
			break;
		default:
			break;
		}
	}

	switch (decoder->sh.slice_type) {
	case P_ONLY:
	case SP_ONLY:
		if (!pps->weighted_pred_flag) {
			break;
		}
		goto pred_weight_table;
	case B:
		if (!pps->weighted_bipred_idc) {
			break;
		}
pred_weight_table:
{
		pred_weight **pw;
		int sz, l = 0;

		decoder->sh.luma_log2_weight_denom = bitstream_read_ue(reader);

		SYNTAX_IPRINT("luma_log2_weight_denom = %u\n",
			      decoder->sh.luma_log2_weight_denom);

		if (ChromaArrayType() != 0) {
			decoder->sh.chroma_log2_weight_denom = bitstream_read_ue(reader);

			SYNTAX_IPRINT("chroma_log2_weight_denom = %u\n",
				      decoder->sh.chroma_log2_weight_denom);
		}
table_fill:
		pw = l ? &decoder->sh.pred_weight_l1 : &decoder->sh.pred_weight_l0;
		sz = (l ? decoder->sh.num_ref_idx_l1_active_minus1 : decoder->sh.num_ref_idx_l0_active_minus1) + 1;
		*pw = realloc(*pw, sizeof(pred_weight) * sz);

		assert(*pw != NULL);

		for (i = 0; i < sz; i++) {
			(*pw)[i].luma_weight_l_flag = bitstream_read_u(reader, 1);

			SYNTAX_IPRINT("luma_weight_l%d_flag[%d] = %u\n",
				      i, l, (*pw)[i].luma_weight_l_flag);

			if ((*pw)[i].luma_weight_l_flag) {
				(*pw)[i].luma_weight_l = bitstream_read_se(reader);

				SYNTAX_IPRINT("luma_weight_l%d[%d] = %u\n",
					      i, l, (*pw)[i].luma_weight_l);
			}
		}

		if (decoder->sh.slice_type != B || l == 1) {
			break;
		}

		l = 1;
		goto table_fill;
}
	default:
		break;
	}

	if (decoder->nal.ref_idc != 0) {
		if (IdrPicFlag) {
			decoder->sh.no_output_of_prior_pics_flag =
						bitstream_read_u(reader, 1);
			decoder->sh.long_term_reference_flag =
						bitstream_read_u(reader, 1);

			SYNTAX_IPRINT("no_output_of_prior_pics_flag = %u\n",
				      decoder->sh.no_output_of_prior_pics_flag);
			SYNTAX_IPRINT("long_term_reference_flag = %u\n",
				      decoder->sh.long_term_reference_flag);
		} else {
			unsigned adaptive_ref_pic_marking_mode_flag;
			uint32_t memory_management_control_operation;
			uint32_t difference_of_pic_nums_minus1;
			uint32_t long_term_pic_num;
			uint32_t long_term_frame_idx;
			uint32_t max_long_term_frame_idx_plus1;

			adaptive_ref_pic_marking_mode_flag =
						bitstream_read_u(reader, 1);

			SYNTAX_IPRINT("adaptive_ref_pic_marking_mode_flag = %u\n",
				      adaptive_ref_pic_marking_mode_flag);

			if (adaptive_ref_pic_marking_mode_flag) {
				do {
					memory_management_control_operation =
								bitstream_read_ue(reader);

					SYNTAX_IPRINT("memory_management_control_operation = %u\n",
						      memory_management_control_operation);

					switch (memory_management_control_operation) {
					case 1:
					case 3:
						difference_of_pic_nums_minus1 =
								bitstream_read_ue(reader);

						SYNTAX_IPRINT("difference_of_pic_nums_minus1 = %u\n",
							      difference_of_pic_nums_minus1);

						if (memory_management_control_operation == 3) {
							goto long_term_frame_idx__;
						}
						break;
					case 2:
						long_term_pic_num =
								bitstream_read_ue(reader);

						SYNTAX_IPRINT("long_term_pic_num = %u\n",
							      long_term_pic_num);
						break;
long_term_frame_idx__:			case 6:
						long_term_frame_idx =
								bitstream_read_ue(reader);

						SYNTAX_IPRINT("long_term_frame_idx = %u\n",
							      long_term_frame_idx);
						break;
					case 4:
						max_long_term_frame_idx_plus1 =
								bitstream_read_ue(reader);

						SYNTAX_IPRINT("max_long_term_frame_idx_plus1 = %u\n",
							      max_long_term_frame_idx_plus1);
						break;
					case 0:
						break;
					default:
						SYNTAX_ERR("memory_management_control_operation is malformed\n");
						break;
					}
				} while (memory_management_control_operation != 0);
			}
		}
	}

	switch (decoder->sh.slice_type) {
	case I:
	case SI:
		break;
	default:
		if (!CABAC_MODE) {
			break;
		}

		decoder->sh.cabac_init_idc = bitstream_read_ue(reader);

		SYNTAX_IPRINT("cabac_init_idc = %u\n", decoder->sh.cabac_init_idc);
	}

	decoder->sh.slice_qp_delta = bitstream_read_se(reader);

	SYNTAX_IPRINT("slice_qp_delta = %d\n", decoder->sh.slice_qp_delta);

	switch (decoder->sh.slice_type) {
	case SP:
		decoder->sh.sp_for_switch_flag = bitstream_read_u(reader, 1);

		SYNTAX_IPRINT("sp_for_switch_flag = %u\n",
			      decoder->sh.sp_for_switch_flag);
	case SI:
		decoder->sh.slice_qs_delta = bitstream_read_se(reader);

		SYNTAX_IPRINT("slice_qs_delta = %d\n",
			      decoder->sh.slice_qs_delta);
		break;
	default:
		break;
	}

	if (pps->deblocking_filter_control_present_flag) {
		decoder->sh.disable_deblocking_filter_idc = bitstream_read_ue(reader);

		SYNTAX_IPRINT("disable_deblocking_filter_idc = %u\n",
			      decoder->sh.disable_deblocking_filter_idc);

		if (decoder->sh.disable_deblocking_filter_idc != 1) {
			decoder->sh.slice_alpha_c0_offset_div2 =
						bitstream_read_se(reader);
			decoder->sh.slice_beta_offset_div2 =
						bitstream_read_se(reader);

			SYNTAX_IPRINT("slice_alpha_c0_offset_div2 = %d\n",
				      decoder->sh.slice_alpha_c0_offset_div2);
			SYNTAX_IPRINT("slice_beta_offset_div2 = %d\n",
				      decoder->sh.slice_beta_offset_div2);
		}
	}

	if (pps->num_slice_groups_minus1 > 0 &&
		pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5)
	{
		int bits_nb = 32 - clz(pps->num_slice_groups_minus1 + 1);

		decoder->sh.slice_group_change_cycle =
						bitstream_read_u(reader, bits_nb);

		SYNTAX_IPRINT("slice_group_change_cycle = %u\n",
			decoder->sh.slice_group_change_cycle);
	}
}
Ejemplo n.º 19
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;
}