数式での翻訳 |
---|
音名の\(4\)つ組\((N_0,N_1,N_2,N_3)\)であって各成分が互いに異なるものを全体の集合を\(\textrm{YonWaOn}\)と置き、\(\textrm{YonWaOn}\)上の\(2\)項関係 \[ (N_{1,0},N_{1,1},N_{1,2},N_{1,3}) \sim (N_{2,0},N_{2,1},N_{2,2},N_{2,3}) \] を\(\{N_{1,0},N_{1,1},N_{1,2},N_{1,3}\} = \{N_{2,0},N_{2,1},N_{2,2},N_{2,3}\}\)と定めます。\(3\)和音の記事で導入した\(\textrm{SanWaOn}\)上の同値関係と同じ記号ですが、これは変化記号の記事で導入したオーバーロードという記号の濫用法に則るものです。\(\sim\)は\(\textrm{YonWaOn}\)上の同値関係となり、\((N_0,N_1,N_2,N_3) \in \textrm{YonWaOn}\)の\(\sim\)に関する同値類 \[ \{(N’_0,N’_1,N’_2,N’_3) \in \textrm{YonWaOn} \mid (N_0,N_1,N_2,N_3) \sim (N’_0,N’_1,N’_2,N’_3)\} \] を\([N_0,N_1,N_2,N_3]\)と置きます。\(\textrm{YonWaOn}\)の元\(\sim\)に関する同値類全体の集合である商集合 \[ \textrm{YonWaOn}/{\sim} = \{[N_0,N_1,N_2,N_3] \mid (N_0,N_1,N_2,N_3) \in \textrm{YonWaOn}\} \] を\(\overline{\textrm{YonWaOn}}\)と置き、\(\overline{\textrm{YonWaOn}}\)の元を\(4\)和音と呼びます。流儀によっては\((\textrm{Do}3,\textrm{Mi}4,\textrm{So}4,\textrm{Si♭}5)\)等の適当な条件を満たすピッチの有限列を\(4\)和音と呼ぶかもしれませんが、ここではそれに類する概念を後に改めて定義し\(4\)和音の配置と呼んで区別していきます。
\(3\)和音と同様、\(4\)和音に関してはそれ以上何も述べることがないので商集合と写像のwell-defined性に関する数学の復習をします。\(\sim\)の定義から、\((N_0,N_1,N_2,N_3) \in \textrm{YonWaOn}\)を集合\(\{N_0,N_1,N_2,N_3\}\)に対応させる写像は\(\overline{\textrm{YonWaOn}}\)から濃度\(4\)である\(\textrm{OnMei}\)の部分集合全体の集合へのwell-definedな全単射を誘導します。その全単射により両者を同一視することで、\(4\)和音を単に濃度\(4\)の\(\textrm{OnMei}\)の部分集合とみなします。
写像 \[ \begin{align} \textrm{YonWaOn} \times \{0,1,2,3\} & \to \textrm{OnMei} \\
((N_0,N_1,N_2,N_3),i) & \mapsto N_i \end{align} \] を\(\textrm{GetOnMei}\)と置きます。すると\((\textrm{Do},\textrm{Re},\textrm{Mi},\textrm{Fa}) \sim (\textrm{Re},\textrm{Do},\textrm{Mi},\textrm{Fa})\)である一方で \[ \textrm{GetOnMei}((\textrm{Do},\textrm{Re},\textrm{Mi},\textrm{Fa}),0) = \textrm{Do} \neq \textrm{Re} = \textrm{GetOnMei}((\textrm{Re},\textrm{Do},\textrm{Mi},\textrm{Fa}),0) \] となります。このことから、\(\textrm{GetOnMei}\)はwell-definedな写像\(\overline{\textrm{YonWaOn}} \times \{0,1,2,3\} \to \textrm{OnMei}\)を誘導しないことが分かります。その意味で「\(4\)和音の\(1\)番目の音名」等もまた「\(3\)和音の\(1\)番目の音名」等と同様にill-definedな概念となります。代わりに後に導入する「\(4\)和音の配置の\(1\)番目のピッチ」等はwell-definedとなります。
\(4\)和音\(H\)に対し、\(H = [N_0,N_1,N_2,N_3]\)を満たす\((N_0,N_1,N_2,N_3) \in \textrm{YonWaOn}\)を\(H\)の代表元と呼びます。\(H\)の代表元は一意でなく、実際\((N_0,N_1,N_2,N_3)\)が\(H\)の代表元であるならば\((N_1,N_0,N_2,N_3)\)は\((N_0,N_1,N_2,N_3)\)と異なる\(H\)の代表元となります。
C++での宣言 |
---|
4和音のクラスおよび関係する関数たちを以下のように宣言します。
class YonWaOn
{
private:
OnMei m_N0;
OnMei m_N1;
OnMei m_N2;
OnMei m_N3;
public:
inline YonWaOn( const OnMei& N0 , const OnMei& N1 , const OnMei& N2 , const OnMei& N3 ) noexcept;
inline bool IsValid() const noexcept;
inline string Display() const noexcept;
const OnMei& GetOnMei( const uint& i ) const noexcept;
};
bool operator==( const YonWaOn& H1 , const YonWaOn& H2 ) noexcept;
inline bool operator!=( const YonWaOn& H1 , const YonWaOn& H2 ) noexcept;
C++での定義 |
---|
実際の実装例についてはこちらをご覧下さい。実装においては以下の仕様を要請します。
inline YonWaOn::YonWaOn( const OnMei& N0 , const OnMei& N1 , const OnMei& N2 , const OnMei& N3 ) noexcept
はメンバ初期化子m_N0( N0 )
,m_N1( N1 )
,m_N2( N2 )
,m_N3( N3 )
で定める。inline bool YonWaOn::IsValid() const noexcept
はreturn m_N0 != m_N1 && m_N1 != m_N2 && m_N2 != m_N3 && m_N3 != m_N0
で定める。inline string YonWaOn::Display() const noexcept
はreturn "(" + m_N0.Display() + "," + m_N1.Display() + "," + m_N2.Display() + "," + m_N3.Display() + ")"
で定める。const OnMei& YonWaOn::GetOnMei( const uint& i ) const noexcept
はi < 4
ならばm_N0
,m_N1
,m_N2
,m_N3
のi+1
番目へのconst 参照返しである。bool operator==( const YonWaOn& H1 , const YonWaOn& H2 ) noexcept
はメタな数列\((0,1,2,3)\)を並び替えた数列\((i,j,k,h)\)であってH1.m_N0 == H2.m_Ni
かつH1.m_N1 == H2.m_Nj
かつH1.m_N2 == H2.m_Nk
かつH1.m_N3 == H2.m_Nh
を満たすものが存在することとtrue
を返すことが同値である。inline bool operator!=( const YonWaOn& H1 , const YonWaOn& H2 ) noexcept
はreturn !( H1 == H2 )
で定める。