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;
};