犬ぶよツールズ制作記録

Javaによる研究生活のためのパッケージ、犬ぶよツールズ。
その開発と保守のための備忘録

名前と引数が同じだが無関係なメソッドのオーバーライド

2013-05-26 12:01:04 | Weblog

● 概要

JDK 1.5以降で導入された共変戻り値型によって、名前と引数が同じだが無関係なメソッドのオーバーライドが可能になっている。

 

● 状況

共変戻り値型が使える場合、図のようなオーバーライドが可能である。

前提は

+ あるインターフェイス(図ではInterfaceX)が、自身を戻り値型とするメソッド(図ではmethod(...): InterfaceX)を持つ。

+ あるインターフェイスないしクラス(図ではSuperclassA)が、自身を戻り値型とするメソッド(図ではmethod(...): SuperclassA)を持つ。

+ これらのメソッドmethod(...)は、名前と引数(その数と型と並び順)が一致する。
 
さらに、SuperclassAがInterfaceXを継承もしくは実装しているなら、SuperclassAを継承したクラスのメソッドmethod(...)は自動的に、InterfaceX#method(...): InterfaceXとSuperclassA#method(...):SuperclassAの両方をオーバーライドしたものになる。
 
一方、SuperclassAがInterfaceXを継承・実装しておらず無関係な場合、SuperclassAを継承したクラス(図ではClassB)がInterfaceXを実装しようとすると、2つのメソッドmethod(...)の戻り値型が整合せず、コンパイルできない。
 
この状況で、ClassBがメソッドmethod(...)を共変戻り値型によりmethod(...): ClassBとしてオーバーライドすれば、これはInterfaceX#method(...): InterfaceXとSuperclassA#method(...):SuperclassAの両方をオーバーライドしたものになる。
 
つまり、名前と引数が同じだが無関係なメソッドのオーバーライドが可能である。
 
 
※ この方法に名前はある?
※ この方法と関係するデザインパターンはある?
※ この方法を使って無関係な2つのメソッド(InterfaceX#method(...): InterfaceXとSuperclassA#method(...):SuperclassA)に共通の実装を与えるのが妥当な状況があるとして、これらの2つのメソッドに予め関係を与えておくことはできる?そこに意味はある?
 
 

GraphvizのDOTファイルを生成するライブラリ (jp.inubuyo.bone.graphvizパッケージ)

2013-05-02 17:41:32 | Weblog

● 概要

Graphvizはグラフ可視化のプログラムです。そのうち、dotプログラムは、DOT言語を解釈して有向グラフを描画します。

jp.inubuyo.bone.graphvizパッケージは、有向グラフの情報からDOT言語が書かれたテキストファイルを生成する簡便な方法を提供します。

 

● 基本方針

+ 有向グラフの情報を与えると、それに対応するDOTファイルを生成する機能を持った専用のクラスを作ります。これをGraphvizWriterとします。

+ 有向グラフの情報を様々なオブジェクトが提供できると便利です。そこで、必要な情報はインターフェイスを介してクラスGraphvizWriterとオブジェクトの間でやり取りします。このインターフェイスをGraphvizWritableとします。

+ ライブラリのユーザーは、GraphvizWritableを実装したオブジェクトを用意します。このオブジェクトをGraphvizWriterのメソッドに引数として渡します。これによってDOTファイルを生成します。

 

● クラスGraphvizWriter

DOTファイルを生成する機能を提供します。使い方の仕様は次のようにします。

+ クラスGraphvizWriterの各インスタンスを、生成されるDOTファイルに対応させます。そこで、コンストラクタで生成するDOTファイルのファイル名を受け取ります。

+ ユーザーは描画したいGraphvizWritableのオブジェクト1個について、メソッドwrite(GraphvizWritable): void を1回呼び出すことにします。

+ 全ての描画したいGraphvizWritableオブジェクトについてメソッドwrite()したら、最後にメソッドclose(): voidを呼び出します。これによって、DOTファイルが書きだされます。

 

これに対応して実装を次のようにします。

+ メソッドwrite()で受け取ったGraphvizWritableオブジェクトは、そのまま貯めておく。

+ メソッドclose()で、ファイルを生成し、全てのGraphvizWritableオブジェクトを書き出し、ファイルを閉じる。

+ GraphvizWritableオブジェクトが1個の場合はdigraphとして書き出し、複数ある場合はそれぞれをsubgraphとして書き出す。

+ 1個のGraphvizWritableオブジェクトを指定されたPrintWriterに書き出すpublicでstaticなメソッドprint(GraphvizWritable, PrintWriter)を提供する(※)。この実装はメソッドclose()による書き出しと同じメソッドによる。

 

● インターフェイスGraphvizWritable

現段階では、クラスGraphvizWriter最も単純な表示に対応します。

インターフェイスGraphvizWritableはそのために必要な情報を渡すメソッドを持ちます。

+ グラフ(もしくはサブグラフ)の名前 name(): String、ノードの数 numberOfNodes(): int、辺の数 numberOfEdges(): int

+ 有向グラフの情報は、getNodeName(intid): String、getEdgeStart(int id): String、getEdgeEnd(int id): String で渡します。これらの引数は、0以上でノード/辺の数未満の番号です。

+ セルには、形状・輪郭の色・内部の色を指定できます。DOTのshape, color, fillColorです。メソッドはgetNodeShape(int id): Stringなどです。

+ 辺には、スタイル・色を指定できます。DOTのstyle, colorです。メソッドはgetEdgeStyle(int id): Stringなどです。

 

● インターフェイスGraphvizWritableの実装

手軽に使えるインターフェイスGraphvizWritableの実装として、クラスGraphvizWritable_Simple、クラスGraphvizWritable_Listを

パッケージjp.inubuyo.bone.graphviz.implに置きます。

+ クラスGraphvizWritable_Simpleは、同じ書式のセルと同じ書式の辺から成るグラフ用です。グラフの形状を予め構成できる場合に使えます。

+ クラスGraphvizWritable_Listは、セルと辺のデフォルトの書式を指定でき、個別の書式も指定できます。セルと辺を随時追加してグラフを構成することができます。

 

(使用例)

Jythonによる使用例です。

>>> import jp.inubuyo.bone.graphviz as graphviz
>>> g = graphviz.impl.GraphvizWritable_List('neko')

>>> g.addNode('neko') 

>>> g.addNode('cat')
>>> g.addNode('gato')
>>> g.addEdge('neko', 'cat')
>>> g.addEdge('cat', 'gato')
>>>

これで3つのノード、2つの辺から成る有向グラフが出来ました。

>>> writer = graphviz.GraphvizWriter('nyan')
>>> writer.write(g)
>>> writer.close()
>>>

これでnyan.dotというファイルが生成されます。

中身は

digraph neko{
neko
cat
gato

neko -> cat;
cat -> gato;

}

このようになります。

これをdotコマンドで画像にすると

となります。

 

● まとめ

GraphvizWritableを実装し、あるいはGraphvizWritable_Listを利用して、有向グラフの情報を与えるだけで、DOT言語の詳細を気にすることなくJavaのプログラムから有向グラフを描画できます。

 


多項式のライブラリ (jp.inubuyo.brain.num.func.polynomialパッケージ)

2013-04-11 14:10:20 | Weblog

● 概要

浮動小数点型の係数を持つ多項式を扱うパッケージです。

n変数多項式はn変数関数と見做します。

k<nについて、k変数多項式Pは、n変数多項式であると見做します。

多項式の定数倍、微分、定積分、多項式同士の和・積・冪・代入のアルゴリズムを提供します。

 

● n変数関数としてのn変数多項式

多項式を表す抽象クラスはPolynomialRntoR, PolynomialR2toR, PolynomialRtoRです。

それぞれ、n変数、2変数、1変数の多項式を表します。

変数が少ない方が多い方のクラスを継承することで、任意の多項式がそれより変数が多い多項式と同一視されます。

これらのクラスは対応するインターフェースDifferentiableR*toR, IntegratableR*toRを実装することで微積分の可能な実関数として扱われます。

 

 ● 単項式への分解

多項式は単項式に分解されます。単項式への分解は、多項式の変数の数をいくつと見做すかに依らず決まります。

そこで、抽象クラスPolynomialRntoRは単項式への分解のメソッドtoMonomials()を持ちます。

これを使って、積や代入などを実装します。単項式は抽象クラスとしていくつがのアルゴリズムを提供します。

このとき、例えば、2変数単項式MonomialR2toRの親クラスを、2変数多項式PolynomialR2toRにするか、n変数単項式MonomialRntoRにするか、2つの方針がありえます。

このライブラリの場合は、クラスMonomialR2toRは2変数多項式PolynomialR2toRの計算の実装に使うので、こちらを継承します。

一方で、単項式への分解のメソッドtoMonomials()の戻り値型が、MonomialRntoR.toMonomials()とMonomialR2toR.toMonomials()で整合的でなければなりません。そこで、単項式を表すインターフェースMonomialを用意し、toMonomials()の戻り値型はその配列Monomial[]とします。

クラスMonomialR*toRはインターフェースMonomialを実装します。

 

● まとめ

以上のクラス構造を中心に、多項式の計算アルゴリズムを提供します。

関連するクラスはパッケージjp.inubuyo.brain.num.func.polynomialに収められます。

 


jp.inubuyo.bone.domain (SetOfR) パッケージ

2013-01-05 00:37:06 | Weblog

● 概要

実数の部分集合を表す抽象クラスSetOfRを含むパッケージです。実数といっても実装はdouble型の変数です。有限個の区間からなる部分集合を扱うことができます。

 

● 概念

実数の集合には全順序が入っています。Javaでもdouble型に対して大小関係を与える演算子(==、<、>、>=、<=)があります。これにより特定の区間について、与えられたdouble型の変数がその区間に含まれるか否か判定することができます。

実数の区間は、両端の値と、端でその値を含むか否かを指定すれば定まります。Javaでは正負の無限大(Double.POSITIVE_INFINITY、Double.NEGATIVE_INFINITY)が定義されていて、これも区間の指定に使えます。端の値がdouble型の値になる開区間や閉区間は表すことができます。

 

区間同士の間には順序関係を定めることができます。より小さな値を含む区間をより小さいと定義します。下端が等しい区間同士では、包含関係を順序にします。

 

実数の部分集合に対して、補集合を取る操作が単項演算になります。2つの部分集合の合併を取る操作、共通部分を取る操作が2項演算になります。開区間や閉区間を含む範囲では、有限個の区間からなる集合がこれらの演算について閉じています。

 

● 構成

実数の部分集合を表す抽象クラスSetOfRを作ります。これを継承し、単一の区間を表す抽象クラスIntervalを作ります。また、有限個の区間からなる集合のインスタンスを実装するため、SetOfRの実装クラスSetOfR_SortedSetを用意します。

 

● 抽象クラスSetOfR

与えられた値を含むか否かを判定する抽象メソッドcontains(double): booleanを持ちます。この特性関数をRtoBのインスタンスとして返すメソッドgetRtoB(): RtoBを提供します。

 

部分集合の性質を返す抽象メソッドを持ちます。

+ isOpen(): boolean

+ isClose(): boolean

+ isCompact(): boolean

+ sup(): double

+ inf(): double

 

補集合、合併、共通部分を得るためのメソッドを持ちます。

+ complement(): SetOfR

+ union(SetOfR): SetOfR

+ intersection(SetOfR): SetOfR

 

また、閉包と内点も取れます。

+ closure(): SetOfR

+ interior(): SetOfR

 

SetOfRのインスタンスは(少なくとも現時点の実装では)有限個の区間からなる集合を表します。それらに分解するための抽象メソッドを持ちます。

+ numberOfIntervals(): int

+ intervals(): Interval[]

 

また、集合の測度(1次元体積)を求めるメソッドvolume()を提供します。

 

● 抽象クラスInterval

単一の区間からなる集合は、抽象クラスIntervalのサブクラスで表します。

+ Interval_Empty: SetOfRのサブクラスとしての、空集合を表すクラスです。このクラスはシングルトンで、定数EMPTYを持ちます。

+ Interval_Whole:SetOfRのサブクラスとしての、実数全体の集合(-Infitity, Infinity)を表すクラスです。このクラスはシングルトンで定数WHOLEを持ちます。

+ Interval_Point: 1点からなる集合を表すクラスです。

+ Interval_Closed: 閉区間[a, b]を表すクラスです。properな(aとbが異なる)区間に限ります。

+ Interval_Open:開区間(a, b)を表すクラスです。端点のうち一方は無限大でも構いません。

+ Interval_Neither:端のうち一方が閉じていて他方が開いている区間を表すクラスです。開いている端は無限大でも構いません。

継承したメソッドのうち、closure()とinterior()は共変戻り値でIntervalを返します。

numberOfIntervals()は1を返します。空集合を表すInterval_Emptyだけは例外で0を返します。intervals()は自分自身を要素として持つ長さ1の配列を返します。やはりInterval_Emptyだけは例外で長さ0の配列を返します。

 

SetOfRの抽象メソッドを実装するために、抽象クラスIntervalは以下の抽象メソッドを持ちます。

+ hasIntersectionWith(Interval): boolean

+ isAdjacentTo(Interval): boolean

これらは共通部分があるかどうか、接しているかどうかを判定します。

+ connect(Interval): Interval

共通部分があるかあるいは接している区間との合併を作ります。

 

区間の順序を与えるために抽象クラスIntervalはjava.lang.Comparableを継承します。

 

● クラスSetOfR_SortedSet

複数の区間から成る集合を表すためのクラスです。現時点ではInterval以外で唯一のSetOfRの実装クラスです。データとしてIntervalをjava.util.SortedSetに保持しています。

 

Intervalは不変(immutable)ですが、SetOfR_SortedSetは可変(mutable)です。区間を追加するメソッドadd(Interval): voidを持ちます。

 

● 実装

空集合に対応するインスタンスは2種類あります。ひとつはクラスInterval_Emptyの定数Interval_Empty.EMPTYです。クラスSetOfR_SortedSetも初期化した時点では何もadd()されていないので空集合を表します。このライブラリの実装は、戻り値が空集合になる場合には必ずInterval_Empty.EMPTYを返します。

 

実数全体の集合に対応するインスタンスは定数Interval_Whole.WHOLEのみです。戻り値が実数全体の集合になる場合、その値はInterval_Whole.WHOLEです。

 

単一の区間からなる集合に対応するインスタンスは、Intervalのインスタンスと、SetOfR_SortedSetのadd()が1回呼び出されたインスタンスの2種類あります。戻り値が単一の区間からなる集合になる場合には、Intervalのインスタンスを返すように実装しています。

 

メソッドtoString(): Stringは、Intervalの実装では区間を表すASCII文字列になります。閉区間は"[0.0, 1.0]"、開区間は"(0.0, 1.0)"、1点からなる集合は"{0.0}"の形式です。SetOfR_SortedSetは、区間を表す文字列を文字"U"で結合したものになります。

 

● まとめ

抽象クラスSetOfRにより、有限個の区間からなる実数の集合を扱うことができます。補集合、合併、共通部分を自由に取ることが可能です。抽象クラスSetOfRとIntervalはパッケージjp.inubuyo.bone.domainに、これらの実装クラスはパッケージjp.inubuyo.bone.domain.implにあります。

 


jp.inubuyo.bone.domain.core (RntoB) パッケージ

2013-01-04 20:56:17 | Weblog

● 概要

double[]を引数としbooleanを戻り値とする写像を表す抽象クラスRntoBを提供するパッケージです。

Inubuyo Logic (BntoB) Libraryに依存します。

 

● 構成

抽象クラスRntoBは、抽象メソッドvalue(double[]): booleanを持ちます。

メソッドvalue(double[]): booleanは、引数の配列の0番目からn番目の要素により定まるものとします。

この、依存する要素の数を抽象メソッドsize(): intにより返します。

valueメソッドの引数には長さがsize()以上の配列を指定してください。

短い場合には、RntoBの実装クラスはArrayIndexOutOfBoundsExceptionを送出することができます。

 

size()が1、つまり配列の最初の要素のみに依存するRntoBのインスタンスは自然に、doubleを引数としbooleanを返すメソッドと見做せます。

これを抽象クラスRtoBとその抽象メソッドvalue(double): booleanで表します。

同様に、size()が2のRntoBのインスタンスは抽象メソッドvalue(double, double): booleanで表せます。

これを抽象クラスR2toBとします。

抽象クラスR2toBはRntoBを継承し、抽象メソッドvalue(double, double): booleanで継承したメソッドvalue(double): booleanを実装します。抽象クラスRtoBはR2toBを継承し、抽象メソッドvalue(double): booleanで継承したメソッドvalue(double, double): booleanを実装します。

 

定値関数はsize()が0になります。このインスタンスは、クラスRtoB_Constantの定数RtoB_Constant.TRUE、RtoB_Constant.FALSEとして提供します。

 

boolean値に対する単項演算not(否定)から、RntoBに対する単項演算が定まります。これをクラスRntoBのメソッドnot(): RntoBで提供します。

メソッドnot()は共変戻り値型になります。つまり、RntoB#not(): RntoB、 R2toB#not(): R2toB、RtoB#not(): RtoBです。

 

boolean値に対する二項演算から、RntoBに対する二項演算が定まります。これをRntoBのメソッドoperateWith(B2toB, RntoB): RntoB

で提供します。特に、可換な二項演算についてはメソッドを提供します。

+ and(RntoB): RntoB

+ or(RntoB): RntoB

+ xor(RntoB): RntoB

+ nand(RntoB): RntoB

+ nor(RntoB): RntoB

+ nxor(RntoB): RntoB

二項演算に対してはサブクラスで引数の異なるメソッドが提供されます。つまり、R2toB#and(R2toB): R2toB、RtoB#or(RtoB): RtoBなどです。
 
R2toBのメソッドvalue(double, double): booleanの第2引数に値を代入したものを考えると、これはRtoBになります。
同様に第1引数に代入してもRtoBになります。これらをメソッドR2toB#substitute0(double): RtoB、R2toB#substitute1(double): RtoBで提供します。引数は代入する値です。
RtoBはsubstitute1(double): RtoBを自分自身を返すメソッドとしてオーバーライドします。また、substitute0(double): RtoBをRtoB_Constantを返すメソッドとしてオーバーライドします。
 
これと同様に、RntoBは代入した写像のインスタンスを返すメソッドsubstitute(int, double): RntoBを持ちます。引数は代入する成分のインデックス(第1引数)と代入する値(第2引数)です。
 
集合R^nから集合Bへの写像fと、集合R^mから集合Bへの写像gと、B上の2項演算・から、直積写像:R^n×R^m → Bが、(x, y)をf(x)・g(y)に写す写像として定義されます。これを、メソッドRntoB#directProduct(B2toB, RntoB): RntoBにより提供します。RtoB同士の場合には戻り値がR2toBになるので、型が異なるメソッドRtoB#directProduct(B2toB, RtoB): R2toBもあります。
 
● まとめ
以上、RntoBに関わる抽象クラスをjp.inbuyo.bone.domain.coreパッケージに収めます。実装に必要なクラスがjp.inubuyo.bone.domain.core.implにあります。

Inubuyo Logic (BntoB) Libraryの使用例

2012-12-19 00:53:05 | Weblog

● 概要

Inubuyo Logicの使用例をJythonで。

 

● 準備

Jythonを起動して、パッケージjp.inubuyo.bone.logicをimportします。

inubuyo@~$ jython
Jython 2.5.2 (Release_2_5_2:7206, Mar 2 2011, 23:12:06)
[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_37
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> import jp.inubuyo.bone.logic as logic
>>>

この時点で、size()が2以下の全ての写像に対応するB2toBのインスタンスが利用できます。

全16個あります。

>>> logic.BtoBs.FALSE
jp.inubuyo.bone.logic.impl.BtoB_Constant[false]
>>> logic.BtoBs.TRUE
jp.inubuyo.bone.logic.impl.BtoB_Constant[true]
>>> logic.BtoBs.ID
jp.inubuyo.bone.logic.impl.BtoB_Id[]
>>> logic.BtoBs.NOT
jp.inubuyo.bone.logic.impl.BtoB_Not[]
>>>

以上の4個はBtoBのインスタンスです。定値関数の2つはarity()が0、残りの2つはarity()が1です。

B2toBsにも同じインスタンスにアタッチされた定数があります。

>>> logic.B2toBs.FALSE
jp.inubuyo.bone.logic.impl.BtoB_Constant[false]

>>> logic.B2toBs.TRUE
jp.inubuyo.bone.logic.impl.BtoB_Constant[true]
>>> logic.B2toBs.P1
jp.inubuyo.bone.logic.impl.BtoB_Id[]
>>> logic.B2toBs.NOT_P1
jp.inubuyo.bone.logic.impl.BtoB_Not[]

 

以下の12個はB2toBのインスタンスです。

>>> logic.B2toBs.P2
jp.inubuyo.bone.logic.impl.B2toB_Injection2[jp.inubuyo.bone.logic.impl.BtoB_Id[]]
>>> logic.B2toBs.NOT_P2
jp.inubuyo.bone.logic.impl.B2toB_Not[jp.inubuyo.bone.logic.impl.B2toB_Injection2[jp.inubuyo.bone.logic.impl.BtoB_Id[]]]

ここまではarity()が1のもので、以降が2項演算です。

2項演算は10個あります。

>>> logic.B2toBs.AND
jp.inubuyo.bone.logic.impl.B2toB_And@16916f80
>>> logic.B2toBs.OR
jp.inubuyo.bone.logic.impl.B2toB_Or@651ee017
>>> logic.B2toBs.XOR
jp.inubuyo.bone.logic.impl.B2toB_Xor@618eabf6
>>> logic.B2toBs.NAND
jp.inubuyo.bone.logic.impl.B2toB_Not[jp.inubuyo.bone.logic.impl.B2toB_And@16916f80]
>>> logic.B2toBs.NOR
jp.inubuyo.bone.logic.impl.B2toB_Not[jp.inubuyo.bone.logic.impl.B2toB_Or@651ee017]
>>> logic.B2toBs.NXOR
jp.inubuyo.bone.logic.impl.B2toB_Not[jp.inubuyo.bone.logic.impl.B2toB_Xor@618eabf6]
>>> >

この6つが可換な2項演算です。

>>> logic.B2toBs.P1_OR_NOT_P2
jp.inubuyo.bone.logic.impl.B2toB_Not[jp.inubuyo.bone.logic.impl.B2toB_Composite@78c6cbc]
>>> logic.B2toBs.P1_AND_NOT_P2
jp.inubuyo.bone.logic.impl.B2toB_Not[jp.inubuyo.bone.logic.impl.B2toB_Composite@4e84f566]
>>> logic.B2toBs.NOT_P1_AND_P2
jp.inubuyo.bone.logic.impl.B2toB_Composite@78c6cbc
>>> logic.B2toBs.NOT_P1_OR_P2
jp.inubuyo.bone.logic.impl.B2toB_Composite@4e84f566
>>>

この4つが非可換な2項演算です。

● 定値関数

定値関数B2toBs.FALSEのvalueメソッドには、何を与えてもFalseが返ってきます。

>>> f0 = logic.B2toBs.FALSE
>>> f0.value(True)
False
>>> f0.value(False)
False
>>> f0.value(True, False)
False
>>> f0.value([False, False])
False
>>>

これに対して、定値関数B2toBs.TRUEのvalueメソッドには、何を与えてもTrueが返ってきます。

>>> f1 = logic.B2toBs.TRUE
>>> f1.value(True)
True
>>> f1.value(False)
True
>>> f1.value(True, False)
True
>>> f1.value([False, False])
True
>>>

 

B2toBs.FALSEのbitwiseメソッドには、何を与えても0が返ってきます。

>>> f0.bitwise(5)
0L
>>> f0.bitwise(10L)
0L

Jythonでは、引数の型をintにしてもlong型として扱われています。

 

B2toBs.TRUEのbitwiseメソッドは、符号付き整数型に対しては-1が返ってきます。

>>> f1.bitwise(5)
-1L
>>> f1.bitwise(10L)
-1L

全ビットを1にするからです。

 

定値関数はsize()、arity()とも0です。

>>> f0.size()
0
>>> f1.size()
0
>>> f0.arity()
0
>>> f1.arity()
0

 

IDは、FALSEが0、TRUEが1です。

>>> f0.toID()
0L
>>> f1.toID()
1L

 

● 単項演算

BtoBs.IDは恒等写像、BtoBs.NOTは否定です。

>>> f2 = logic.BtoBs.ID 

>>> f2.value(True)
True
>>> f2.value(False)
False

>>> f3 = logic.BtoBs.NOT

>>> f3.value(True) 

False
>>> f3.value(False)
True
>>>

BtoBs.IDのnot()は、BtoBs.NOTです。

>>> f2.not() == logic.BtoBs.NOT
True
>>>

同一のインスタンスです。
 
 
BtoBs.IDは3番、BtoBs.NOTは4番です。

>>> f2.toID()
2L

>>> f3.toID()
3L

 

今日はここまで。

 

 


Inubuyo Logic (BntoB) Library version 0.1.0

2012-12-18 18:05:10 | Weblog

● 概要
論理値全体の集合をBとして、自然数nについて写像B^n --> Bを扱うライブラリです。写像B^n --> Bは、Javaでは、引数にboolean型の配列を取る戻り値boolean型のメソッドに対応します。

● 基本方針
論理値全体の集合Bは2つの元からなります。Bには、補元を取る単項演算(否定)と、2項演算(AND, ORなど)が定義されています。
Javaでは、集合Bはboolean型で表されます。boolean型の変数x, yに対し、xの否定!x、xとyのANDのx && y、ORの x || y、XORの x != yが使えます。

集合Bの直積集合B^nから集合Bへの写像を考えます。n=1なら4通り(恒等写像、否定、定値写像2つ)の写像があります。n=2なら16通り、一般のnに対しては2^(2^n)通りになります。Javaの長さnのboolean型の配列aは、直積集合B^nの元と見做すことができ、直積集合B^nから集合Bへの写像は、引数にboolean型の配列を取る戻り値boolean型のメソッドになります。

集合B^2から集合Bへの写像のうち、引数の配列の最初の要素のみに依存するものは、BからBへの写像と見做せます。一般に正整数m<nについて、集合B^nから集合Bへの写像のうち、引数の最初のm個の要素のみに依存するものは、B^mからBへの写像と見做せます。このmをこの写像のsizeと呼ぶことにします。
この同一視の下で、これらの写像を抽象クラスBntoBで表すことにします。ここまでで、BntoBが持つ抽象メソッドは次の2つです。
+ value(boolean[]): boolean
+ size(): int

BntoBを継承したB2toB、B2toBを継承したBtoBも用意します。

B2toBが継承するメソッドvalue(boolean[]): booleanは抽象メソッドvalue(boolean, boolean): booleanで実装されます。BtoBが継承するメソッドvalue(boolean, boolean): booleanは抽象メソッドvalue(boolean): booleanで実装されます。

● 整数型に対するbitwiseメソッド
BからBへの写像は、単項演算として整数に2進数の桁毎(bitwise)に作用することができます。Javaでも整数型に対するbitwiseの否定の演算子~が定義されています。クラスBtoBはこれを抽象メソッドとして提供します。
+ bitwise(int): int
+ bitwise(long): long
+ bitwise(short): int
+ bitwise(byte): int
引数がshort型, byte型の場合に戻り値がint型になるのは演算子~に従ったものです。

同様に、B^2からBへの写像は、2項演算として整数の組にbitwiseに作用することができます。Javaでも整数型に対する演算子&, |, ^が定義されています。クラスB2toBはこれを抽象メソッドとして提供します。
+ bitwise(int, int): int
+ bitwise(long, long): long
+ bitwise(short, short): int
+ bitwise(byte, byte): int
ここでも引数がshort型, byte型の場合に戻り値がint型になるのは&などの演算子に従ったものです。

このbitwiseな演算はそのまま任意の項数に拡張できます。クラスBntoBはこれを抽象メソッドとして提供します。
+ bitwise(int[]): int
+ bitwise(long[]): long
+ bitwise(short[]): int
+ bitwise(byte[]): int
当然のことながら、これらはメソッドvalue(boolean[]): booleanとコンシステントに動作しなければなりません。

● 写像間の演算
論理値に対する演算により、集合B^nから集合Bへの写像に対する演算が自然に定まります。クラスBntoBではこれを抽象メソッドにより扱うことができます。

単項演算は引数が無いメソッドです。
+ not(): BntoB
これは否定を返します。

2項演算は引数を1つ取るメソッドです。
+ and(BntoB): BntoB
+ or(BntoB): BntoB
+ xor(BntoB): BntoB
+ nand(BntoB): BntoB
+ nor(BntoB): BntoB
+ nxor(BntoB): BntoB
+ implies(BntoB): BntoB

メソッドnot()は共変戻り値型です。B2toB#not()はB2toBを返し、BtoB#not()はBtoBを返します。2項演算については、B2toB#and(BntoB): BntoBとB2toB#and(B2toB): B2toBのように、引数の型が異なるメソッドが提供されます。

● 認識番号(ID)
写像B^n --> Bと自然数の間に1対1対応を構成してあります。これにより、次のようなことが容易に実装されます。
+ BntoBの異なるインスタンスが、写像B^n --> Bとして等しいか否か判定する。
+ 自然数kに対し、sizeがk以下の写像B^n --> Bを全て列挙する。
+ BntoBのインスタンスが必要になったとき、その写像に対応するインスタンスが既に生成されていたら、それを使う。

BntoBのインスタンスのIDはメソッドtoID(): longで得られます。IDからインスタンスを得るには、クラスBntoBsのクラスメソッドid(long):BntoBを使います。このクラスBntoBsはメソッド・ファクトリーです。

● 代入
自然数k < nについて、写像B^n --> Bのk番目の引数に値を代入すると、別の写像が得られます。クラスBntoBでは、メソッドsubstitute(int, boolean): BntoBでこの操作を提供します。

● 依存項数(arity)
size()がnであるBntoBのインスタンスのメソッドvalue(boolean[])は、戻り値を計算するために、引数の1番目からn番目の要素を使うことができます。一方で、戻り値が引数の1番目からn番目の要素全てに依存するとは限りません。例えば、引数の2番目の要素をそのまま返す写像

public boolean value(boolean[] x) { return x[1]; }

の場合、size()は2ですが、引数のうちの1個の要素にしか依存していません。

クラスBntoBでは、そのインスタンスが実際に依存している要素の個数をメソッドarity()で返します。上の例では、arity()の値は1です。

● まとめ
以上が主要な仕様です。これらのクラスをjp.inubuyo.bone.logicパッケージに入れます。抽象クラスBntoBの実装はjp.inubuyo.bone.logic.implパッケージにあります。


Inubuyo Factor Latticeの実行例

2012-11-21 12:55:34 | Weblog
Inubuyo Factor Latticeの実行例です。


> java -jar inubuyo-factor-lattice-0.1.1.jar -f lightskyblue1 -c royalblue4 -e royalblue4 -o lat 60
> dot -Tpng lat60.dot -o lat60.png




> java -jar inubuyo-factor-lattice-0.1.1.jar -f greenyellow -c forestgreen -e green -o lat 120
> dot -Tpng lat120.dot -o lat120.png




> java -jar inubuyo-factor-lattice-0.1.1.jar -f salmon1 -c chocolate -e gray60 -o lat 128
> dot -Tpng lat128.dot -o lat128.png




> java -jar inubuyo-factor-lattice-0.1.1.jar -o lat 180
> dot -Tpng lat180.dot -o lat180.png




> java -jar inubuyo-factor-lattice-0.1.1.jar -o lat 210
> dot -Tpng lat210.dot -o lat210.png




> java -jar inubuyo-factor-lattice-0.1.1.jar -o lat 420
> dot -Tpng lat420.dot -o lat420.png




> java -Xmx512M -jar inubuyo-factor-lattice-0.1.1.jar -c gray60 -e gray60 -o lat 2778545904897799
> dot -Tpng lat2778545904897799.dot -o lat2778545904897799.png



※ 正整数Nの因数の集合には、最小公倍数をとる二項演算lcm、最大公約数をとる二項演算gcdが入り(N, lcm, gcd)は束になる。これは1を最小元、Nを最大元とする可補束で、aの補元はN/aである。この性質により、Nの有向グラフは、aをN/aで置き換え、矢印の向きを逆にし、180°回転すると元のグラフと等しくなる。

Inubuyo Factor Lattice (ver.0.2.0 release)

2012-11-21 11:18:07 | Weblog
● 概要
ある正整数の因数の集合は束(lattice)になります。束は有向グラフとして表示することができます。Inubuyo Factor Latticeは因数の集合が成す束を表す有向グラフを生成します。
例えば、こんな図です。


(インストールなど)
● 動作環境
+ Java。JRE 1.4以上。

生成した有向グラフのデータを画像にするには次が必要です。
+ Graphizのdotコマンド

● 動作環境
+ JARファイル
inubuyo-factor-lattice-0.1.1.jar
+ JARファイル(ソースのみ)
inubuyo-factor-lattice-0.1.1src.jar



● 利用条件
フリーです。

(使い方)
● 実行方法
コマンドラインから実行します。inubuyo-factor-lattice-0.1.1.jarを置いたディレクトリで

> java -jar inubuyo-factor-lattice-0.1.1.jar

とするとヘルプを表示します。


USAGE: java jp.inubuyo.cell.FactorLattice [options] integer [integers]
options:
o: prefix of the output file. If specified, the filename is prefix+number+".dot". Default value is standard out.
c: color of cells. Default value is null (DOT default).
f: fill color of cells. Default value is no color.
s: edge style. Default value is null (DOT default).
e: color of edges. Default value is null (DOT default).


inubuyo-factor-lattice-0.1.1.jarにパスが通っていれば

java jp.inubuyo.cell.FactorLattice

でも同じです。

因数分解したい正整数を引数に指定します。

> java -jar inubuyo-factor-lattice-0.1.1.jar 2

すると有向グラフを表すデータが出力されます。

digraph G{
2 -> 1;
}

この出力の意味はわからなくても構いません。

出力ファイルのプレフィックスを指定します。

> java -jar inubuyo-factor-lattice-0.1.1.jar -o lattice 2

するとこの例では、lattice2.dotというファイルが作られます。

このファイルからPNG画像を作りましょう。Graphizのdotコマンドを使います。

> dot -Tpng lattice2.dot -o lattice2.png

するとこの例では、lattice2.pngというファイルが作られます。こうなります。


● 色などの変更
セルの輪郭の色を変えるには-cオプションを使います。

> java -jar inubuyo-factor-lattice-0.1.1.jar -c blue -o blue 2
> dot -Tpng blue2.dot -o blue2.png

こうなります。


セルの輪郭の色を変えるには-fオプションを使います。

> java -jar inubuyo-factor-lattice-0.1.1.jar -f yellow 2

これでPNG画像を作るとこうなります。


矢印の線種を変えるには-sオプションを使います。

> java -jar inubuyo-factor-lattice-0.1.1.jar -s dashed 2

こうなります。


矢印の色を変えるには-eオプションを使います。

> java -jar inubuyo-factor-lattice-0.1.1.jar -e red 2



以上。

パッケージ jp.inubuyo.bone.disc.core (Version 0.0)

2012-11-19 23:40:00 | about
● 概要
パッケージjp.inubuyo.bone.disc.coreは、組合せの個数や素因数分解を含むint型の計算を収めている。

● クラスNumerics
+ 指数 pow(int, int): int
+ 階乗 factorial(int):int
+ 組合せ combination(int, int): int
+ 重複組合せ multicombination(int, int): int
+ 順列 permutation(int, int): int
+ 最大公約数 gcd(int, int): int
+ 最小公倍数 lcm(int, int): int

● クラスPrimes
素数を小さい順に並べた数列を表す。2, 3に始まりN番目の素数PまでN個の素数を保持する。以下の能力を持つ。
+ 0以上N未満の正整数に対して、N+1番目の素数を返す。メソッドget(int):int。
+ P^2までの正整数について、素数か否かを判定する。メソッドisPrime(int):boolean。
+ Pまでの素数について何番目の素数かを判定する。メソッドtoID(int): int。合成数については-1を返す。

このクラスはシングルトンで使うことができる。クラス・メソッドgetInstance(int)。

● クラスFactorization
正整数を素因数分解する。素因数がint型で表せる、つまり2^31-1以下の素因数からなるlong型の正整数を分解できる。
分解した素因数を小さい順に並べた数列と、各素因数の冪を保持している。
+ numberOfPrimeFactors(): int
+ getPrimeFactor(int): int
+ getIndex(int):

さらに、全ての因数をint型の配列で返すメソッドがある。
+ getFactors(): int[]

以上。