このブログは、旧・はてなダイアリー「檜山正幸のキマイラ飼育記 メモ編」(http://d.hatena.ne.jp/m-hiyama-memo/)のデータを移行・保存したものであり、今後(2019年1月以降)更新の予定はありません。

今後の更新は、新しいブログ http://m-hiyama-memo.hatenablog.com/ で行います。

N上の掛け算による遷移の圏

[追記]eqObjが定義されていると仮定できるなら、SomeCat.composable(f, g)(fとgのこの順での結合可能性)は次のように書けますね。


return SomeCat.eqObj(SomeCat.cod(f), SomeCat.dom(g));
今度からこう書こう。以前のは直さないけど。[/追記]


/* MTNCat.js -- 'Multiplicative Transition over N' Category */

/* 一般的にも使えそうな関数(大域関数) */

// 自然数(0を含む)かどうかを判定する
function isNaturalNumber(x) {
return (
typeof x === 'number' && Math.floor(x) === x
&&
x >= 0
);
}

// 正の自然数かどうかを判定する
function isPositiveNaturalNumber(x) {
return (
typeof x === 'number' && Math.floor(x) === x
&&
x > 0
);
}

/* ここから圏の定義 */

// 名前空間を提供するオブジェクト
var MTNCat = {
};

// 内部的に使うコンストラク
function _MTNCat(n, x) {
if (!isNaturalNumber(n) || !isPositiveNaturalNumber(x))
throw "invalid argument";
this.dom = n;
this.mult = x;
}

// 射の印字のために
_MTNCat.prototype.toString = function() {
var s = "*" + this.mult + " : " +
this.dom + " --> " + (this.dom*this.mult) + "\n";
return s;
};

// この圏の対象かどうかを判定
MTNCat.isObject = function(x) {
return isNaturalNumber(x);
};

// この圏の射かどうかを判定
MTNCat.isMorphism = function(x) {
return (
typeof x === 'object' && x instanceof _MTNCat
);
};

// 射の域
MTNCat.dom = function(f) {
if (!MTNCat.isMorphism(f)) throw "not a morphism";
return f.dom;
};

// 射の余域
MTNCat.cod = function(f) {
if (!MTNCat.isMorphism(f)) throw "not a morphism";
return f.dom * f.mult;
};

// fとgが結合(合成)可能かどうかを判定
MTNCat.composable = function(f, g) {
if (!MTNCat.isMorphism(f) || !MTNCat.isMorphism(g))
throw "not a morphism"; // 今回からエラーとする
return MTNCat.cod(f) === MTNCat.dom(g); // 結合可能性の条件

};

// fとgを結合(合成)
MTNCat.compose = function(f, g) {
if (!MTNCat.composable(f, g)) throw "cannot compose";
return new _MTNCat(f.dom, f.mult*g.mult);
};

// 恒等
MTNCat.id = function(n) {
if (!MTNCat.isObject(n)) throw "not an object";
return new _MTNCat(n, 1);
};

// 対象のコンストラク
MTNCat.obj = function(n) {
if (!isNaturalNumber(n)) throw "invalid argument";
return n;
};

// 射のコンストラク
MTNCat.mor = function(n, x) {
// ここでパラメータチェックは不要、_MTNCatがやるから
return new _MTNCat(n, x);
};

// 対象が等しいかどうかを判定
MTNCat.eqObj = function(n, m) {
if (!MTNCat.isObject(n) || !MTNCat.isObject(m))
throw "not an object";
return n === m;
};

// 射が等しいかどうかを判定
MTNCat.eqMor = function(f, g) {
if (!MTNCat.isMorphism(f) || !MTNCat.isMorphism(g))
throw "not a morphism";
if (f.dom != g.dom || f.cod != g.cod)
return false;
if (f.mult != g.mult) {
return false;
}
return true;
};