⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tape.cpp

📁 The program simulates a Nondeterministic Multitape Turing Machine. It works as ordinary (Determinist
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ==============================================================
//
//  Copyright (c) 2002-2003 Alex Vinokur.
//
//  ------------------------------------------------------------
//  This file is part of C++ Simulator of a Nondeterministic Turing Machine.
//
//  C++ Simulator of a Nondeterministic Turing Machine is free software; 
//  you can redistribute it and/or modify it
//  under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License,
//  or (at your option) any later version.
//
//  C++ Simulator of a Nondeterministic Turing Machine is distributed in the hope 
//  that it will be useful, but WITHOUT ANY WARRANTY; 
//  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
//  See the GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with C++ Simulator of a Nondeterministic Turing Machine; 
//  if not, write to the Free Software Foundation, Inc., 
//  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//  ------------------------------------------------------------
// 
//  mailto:alexvn@connect.to
//  http://up.to/alexv
//
// ==============================================================


// ##############################################################
//
//  SOFTWARE : Nondeterministic Turing Machine (C++ Simulator)
//  FILE     : tape.cpp
//
//  DESCRIPTION :
//         Class Tape (Implementation)
//
// ##############################################################




// ###############
#include "tape.h"


// =========
#define	LEFT_USUAL_DELIM	" "
#define	RIGHT_USUAL_DELIM	" "
#define	LEFT_SCAN_DELIM		"["
#define	RIGHT_SCAN_DELIM	"]"

// #define	SEMI_TAPES_DELIM	"--- "
#define	SEMI_TAPES_DELIM	""


// =========
// Constructor-0
Tape::Tape (
	const vector<symbol_t>& empty_symbols_alphabet_i, 
	const vector<symbol_t>& internal_alphabet_i,
	const vector<symbol_t>& input_alphabet_i,
	const string&           msg_i
	) 
	:
	empty_symbols_alphabet_ (empty_symbols_alphabet_i),
	internal_alphabet_ (internal_alphabet_i),
	input_alphabet_ (input_alphabet_i),
	logical_position_ (HEAD_START_POSITION_DEFAULT),
	max_symbol_size_ (0)
{
  IF_NOT_EMPTY (msg_i, 3, '=');

  check_results_ = check_alphabet ();
  set_max_symbol_size_ ();
  //show_alphabet ("Tape constructed");

} 

// =========
// Destructor
Tape::~Tape ()
{
}
 
// =========
void Tape::clear_it ()
{
  logical_position_ = HEAD_START_POSITION_DEFAULT;

  right_semi_tape_.clear();
  right_semi_tape_.resize ((logical_position_ >= 0) ? logical_position_ : 0);

  left_semi_tape_.clear();
  left_semi_tape_.resize ((logical_position_ < 0) ? labs(logical_position_) : 0);

  cell_visits_.clear();

} 



// =========
void Tape::set_input (const vector<symbol_t>& input_words_i, long init_pos_i)
{
  assert (init_pos_i >= 0);

  logical_position_ = init_pos_i;

  assert (logical_position_ >= 0); // actual_semi_tape is right
  assert ((ulong(logical_position_) + input_words_i.size()) < LONG_MAX);

  assert (ulong(logical_position_) < input_words_i.size());

  copy (input_words_i.begin(), input_words_i.end(), back_inserter(right_semi_tape_));

  assert (get_actual_position () < right_semi_tape_.size());

  /*
  ################## old ##################
  if (actual_semi_tape_is_right ())
  {
    right_semi_tape_.resize(get_actual_position ());

    for (ulong k = 0; k < right_semi_tape_.size(); k++)
    {
      right_semi_tape_[k] = empty_symbols_alphabet_.front();
    }
    copy (input_words_i.begin(), input_words_i.end(), back_inserter(right_semi_tape_));

    assert (get_actual_position () < right_semi_tape_.size());

  }
  else
  {
    assert (actual_semi_tape_is_left ());
    assert (logical_position_ < 0);

    for (ulong k = 0; k < left_semi_tape_.size(); k++)
    {
      left_semi_tape_[k] = empty_symbols_alphabet_.front();
    }

    const size_t split_size = MIN_VALUE (left_semi_tape_.size(), input_words_i.size());
    vector<symbol_t> word_head;
    vector<symbol_t> word_tail;
    for (size_t k = 0; k < input_words_i.size(); k++)
    {
      if (k < split_size) word_head.push_back(input_words_i[k]);
      else                word_tail.push_back(input_words_i[k]);
    }
    assert ((word_head.size() + word_tail.size()) == input_words_i.size());
    // -------------------------------
    for (size_t k = 0; k < word_head.size(); k++)
    {
      left_semi_tape_[left_semi_tape_.size() - 1 - k] = word_head[k];
    }

    copy (word_tail.begin(), word_tail.end(), back_inserter(right_semi_tape_));

    assert (get_actual_position () < left_semi_tape_.size());

  }

  #########################################
  */


  // -------------------------

  assert (cell_visits_.empty());
  for (size_t k = 0; k < input_words_i.size(); k++)
  {
    assert (cell_visits_.count (logical_position_ + k) == 0);
    cell_visits_[logical_position_ + k]	= 0;
  }
  assert (cell_visits_.count (logical_position_) == 1);
  assert (cell_visits_[logical_position_] == 0);
  cell_visits_[logical_position_]++;

}



// =========
vector<symbol_t> Tape::get_output_word () const
{
vector<symbol_t> ret_vect;
  copy (left_semi_tape_.rbegin(), left_semi_tape_.rend(), back_inserter(ret_vect));
  copy (right_semi_tape_.begin(), right_semi_tape_.end(), back_inserter(ret_vect));

  assert (!ret_vect.empty());

  while (!ret_vect.empty() && is_empty_symbol(ret_vect.front()))
  {
    ret_vect.erase (ret_vect.begin());  
  }

  while (!ret_vect.empty() && is_empty_symbol(ret_vect.back()))
  {
    ret_vect.erase (ret_vect.end() - 1);  
  }

  return ret_vect;
}


// =========
void Tape::right_shift ()
{
 assert (get_actual_position () < LONG_MAX);

  logical_position_++;
  if (actual_semi_tape_is_left ()) 
  {
    visual_cleaning ();
    return;
  }

  // ---------
  assert (actual_semi_tape_is_right ());
  assert (get_actual_position () <= right_semi_tape_.size());

  if (get_actual_position () == right_semi_tape_.size()) right_semi_tape_.push_back (empty_symbols_alphabet_.front());
  assert (get_actual_position () < right_semi_tape_.size());

}


// =========
void Tape::left_shift ()
{
  assert (get_actual_position () < LONG_MAX);

  logical_position_--;
  if (actual_semi_tape_is_right ()) 
  {
    visual_cleaning ();
    return;
  }

  // ---------
  assert (actual_semi_tape_is_left ());
  assert (get_actual_position () <= left_semi_tape_.size());

  if (get_actual_position () == left_semi_tape_.size()) left_semi_tape_.push_back (empty_symbols_alphabet_.front());
  assert (get_actual_position () < left_semi_tape_.size());

}


// =========
void Tape::shift_position (shift_t shift_i)
{
  assert (is_valid_shift (shift_i));

  if (shift_i == LEFT_SHIFT)  left_shift();
  if (shift_i == RIGHT_SHIFT) right_shift();

  // if (shift_i == NO_SHIFT) : Do nothing

  // --------------------------------
  if (cell_visits_.count (logical_position_) == 0) cell_visits_[logical_position_] = 0;
  cell_visits_[logical_position_]++;

}


// =========
symbol_t Tape::get_scanned_symbol () const
{

symbol_t ret_symbol;
  if (actual_semi_tape_is_right ())
  {
    assert (get_actual_position () < right_semi_tape_.size());
    ret_symbol = right_semi_tape_[get_actual_position ()];

    assert (is_valid_symbol(ret_symbol));
  }
  else
  {
    assert (actual_semi_tape_is_left ());
    assert (get_actual_position () < left_semi_tape_.size());

    ret_symbol = left_semi_tape_[get_actual_position ()];
    assert (is_valid_symbol(ret_symbol));
  }

  return ret_symbol;

}


// =========
ActualLocation Tape::get_actual_location () const
{
ActualLocation	ret_actual_location;
  if (logical_position_ >= 0)
  {
    ret_actual_location.actual_semi_tape_type_ = RIGHT_SEMI_TAPE;
    ret_actual_location.actual_position_       = logical_position_;

    assert (ret_actual_location.actual_position_ <= right_semi_tape_.size());
  }
  else
  {
    ret_actual_location.actual_semi_tape_type_ = LEFT_SEMI_TAPE;
    ret_actual_location.actual_position_       = labs (logical_position_) - 1;

    assert (ret_actual_location.actual_position_ <= left_semi_tape_.size());
  }
  return ret_actual_location;
}


// =========
ulong Tape::get_actual_position () const
{
  return get_actual_location().actual_position_;
}

// =========
bool Tape::actual_semi_tape_is_right () const
{
  return (get_actual_location().actual_semi_tape_type_ == RIGHT_SEMI_TAPE);
}


// =========
bool Tape::actual_semi_tape_is_left () const
{
  return (get_actual_location().actual_semi_tape_type_ == LEFT_SEMI_TAPE);
}



// =========
vector<symbol_t> Tape::get_full_alphabet () const
{
vector<symbol_t>	ret_vector;

  copy (empty_symbols_alphabet_.begin(), empty_symbols_alphabet_.end(), back_inserter(ret_vector));
  copy (input_alphabet_.begin(), input_alphabet_.end(), back_inserter(ret_vector));
  copy (internal_alphabet_.begin(), internal_alphabet_.end(), back_inserter(ret_vector));

  return ret_vector;
}



// =========
void Tape::set_symbol (const symbol_t& symbol_i)
{
  assert (is_valid_symbol(symbol_i));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -