VDM++
だいぶ文法がわかってきたので、簡単なクラスを作ってみました。
まったくの未開の大陸なので、すべてが手作りから始まります。
例えれば、
/** * 有理数のクラス * 分子、分母は整数である。 * 分母は0になることはありえない。 * 分子と分母が割り切れる場合は簡単にする。 * 分母が負の場合、両方にマイナスを掛け、分母は常に正になるようにする。 * * 固定小数点演算もこのクラスを使えば正しく計算できる。 * 例えば、1.05(消費税)は new Rational(105,100)として計算すればよい。 * * VDM++では、有理数は内部的には実数と同じ扱いになっているため、望む機能が得られない場合がある。 * このクラスを使えば、正しい有理数が使えるようになる。(できれば言語側で対応して欲しいのだけれど) * 参考:SICP2nd * @author A-san */ class Rational instance variables public 分子:int := 0; public 分母:int := 1; inv 分母 > 0; operations public Rational: int * int ==> Rational Rational(a,b) == let gcd = GCD(abs a, abs b) in ( if b > 0 then ( 分子 := a div gcd; 分母 := b div gcd ) else ( 分子 := -a div gcd; 分母 := -b div gcd ); return self ) pre b <> 0; public get分子: () ==> int get分子() == return 分子; public get分母: () ==> int get分母() == return 分母; public toReal: () ==> real toReal() == return get分子() / get分母(); /** * 有理数を "分子/分母"の形で表示する. * 分母が1の場合は"分子"の形で表示する。 */ public toString: () ==> seq of char toString() == is not yet specified; functions public static add: Rational * Rational -> Rational add(r1, r2) == new Rational( r1.get分子() * r2.get分母() + r2.get分子() * r1.get分母(), r1.get分母() * r2.get分母() ); public static sub: Rational * Rational -> Rational sub(r1, r2) == new Rational( r1.get分子() * r2.get分母() - r2.get分子() * r1.get分母(), r1.get分母() * r2.get分母() ); public static mul: Rational * Rational -> Rational mul(r1, r2) == new Rational( r1.get分子() * r2.get分子(), r1.get分母() * r2.get分母() ); public static divide: Rational * Rational -> Rational divide(r1, r2) == new Rational( r1.get分子() * r2.get分母(), r1.get分母() * r2.get分子() ); public static equals: Rational * Rational -> bool equals(r1, r2) == r1.get分子() = r2.get分子() and r1.get分母() = r2.get分母(); /** * 文字列から有理数を生成する. * "分子/分母"の形であること。'/'以降がない場合は、分母が1とする。 */ public static parse: seq of char -> Rational parse(s) == is not yet specified; /** * 最大公約数(Greatest Common Divisor) * ユークリッドの互除法. */ functions public static GCD: nat1 * nat1 -> nat1 GCD(a,b) == if b = 0 then a else GCD(b, a rem b); end Rational