Location : Home > Languages > Perl > Package
Title : Math::Logic
Toolbox Logo

名称

 Math::Logic - 多値論理


概要

use Math::Logic qw( $TRUE $FALSE $UNDEF $STR_TRUE $STR_FALSE $STR_UNDEF ) ;
                #       1      0     -1     'TRUE'    'FALSE'    'UNDEF'

use Math::Logic ':NUM' ; # $TRUE $FALSE $UNDEF -- what you normally want

use Math::Logic ':ALL' ; # All the constants

use Math::Logic ':STR' ; # $STR_TRUE $STR_FALSE $STR_UNDEF

# 2値論理
my $true  = Math::Logic->new( -value => $TRUE,  -degree => 2 ) ;
my $false = Math::Logic->new( -value => $FALSE, -degree => 2 ) ;
my $x     = Math::Logic->new_from_string( 'TRUE,2' ) ;

print "true" if $true ;

# 3値論理 (non-propagating)
my $true  = Math::Logic->new( -value => $TRUE,  -degree => 3 ) ;
my $false = Math::Logic->new( -value => $FALSE, -degree => 3 ) ;
my $undef = Math::Logic->new( -value => $UNDEF, -degree => 3 ) ;
my $x     = Math::Logic->new_from_string( 'FALSE,3' ) ;

print "true" if ( $true | $undef ) == $TRUE ;

# 3値論理 (propagating)
my $true  = Math::Logic->new( -value => $TRUE,  -degree => 3, -propagate => 1 ) ;
my $false = Math::Logic->new( -value => $FALSE, -degree => 3, -propagate => 1 ) ;
my $undef = Math::Logic->new( -value => $UNDEF, -degree => 3, -propagate => 1 ) ;
my $x     = Math::Logic->new_from_string( '( UNDEF, 3, -propagate )' ) ;

print "undef" if ( $true | $undef ) == $UNDEF ;

# 多値論理
my $True   = 100 ; # 真値の定義
my $False  = $FALSE ;
my $true   = Math::Logic->new( -value => $True,  -degree => $True ) ;
my $very   = Math::Logic->new( -value => 67,     -degree => $True ) ;
my $fairly = Math::Logic->new( -value => 33,     -degree => $True ) ;
my $false  = Math::Logic->new( -value => $False, -degree => $True ) ;
my $x      = Math::Logic->new_from_string( "25,$True" ) ;

print "maybe" if ( $very | $fairly ) > 50 ;

# We can have arbitrarily complex expressions; the result is a Math::Logic
# object; all arguments must be Math::Logic objects or things which can be
# promoted into such and must all be compatible. The outcome depends on
# which kind of logic is being used.
my $xor = ( $x | $y ) & ( ! ( $x & $y ) ) ; 
# This is identical to:
my $xor = $x ^ $y ;

説明

 Perl の組み込み論理演算子 and, or, xor, not は2値論理をサポートしている。これは結果は常に true または false であることを意味する。しかし実際には perl は時には 0 を返し、演算子や引数の順序などにより undef を返すこともある。"true" については、Perl は一般に true と評価された最初の値を返すが、実際に役に立つ返り値であってほしい。所与の Perl の組み込み論理演算子の選択肢から選ぶことが望ましいが、純粋な2値論理または3値論理または多値論理を実行するには本モジュールを利用すると良い。
 2値論理値は 1 (TRUE) 及び 0 (FALSE) である。
 3値論理値は 1 (TRUE), 0 (FALSE), -1 (UNDEF) である。UNDEF は -1 であって、undef ではないことに注意すること!
 多値論理では 0 (FALSE) から -degree まで -- TRUE の値は degree で指定され、通常 100 までの値をとる。
 -degree は最大値である(2値や3値とは異なる)。すなわち n-degree 論理はis n+1-値の論理である。つまり 100-degree 論理は 101 個の値 0..100 をとる。
 いくつかの有用な定数がエクスポート可能であるが、これはオブジェクトモジュールであり、論理比較の結果は Math::Logic オブジェクトである。

2値論理

 2値論理は各論理演算子に対する真理表を持っている。

    Perl Logic      Perl Logic     Perl Logic 
A B and  and    A B or   or    A B xor  xor
- - ---  ---    - - --   --    - - ---  ---
F F  F    F     F F  F    F    F F  F    F
T T  T    T     T T  T    T    T T  F    F
T F  F    F     T F  T    T    T F  T    T
F T  F    F     F T  T    T    F T  T    T

  Perl Logic
A not  not 
- ---  ---
F  T    T
T  F    F

 上表では Perl の組み込みの T 及び F を扱うにはそれぞれ true または false を当てはめればよい。Math::Logic を用いると、それぞれ 1 及び 0 を値に持つオブジェクトとなる。Perl は false の場合に 0 または undef を返す場合があるが、Math::Logic ではオブジェクトは 0 (FALSE) または 1 (TRUE) しか返さない。

my $true   = Math::Logic->new( -value => $TRUE,  -degree => 2 ) ;
my $false  = Math::Logic->new( -value => $FALSE, -degree => 2 ) ;

my $result = $true & $false ; # my $result = $true->and( $false ) ;

print $result if $result == $FALSE ; 

3値論理

 3値論理では、 "and" 及び "or" について2つの異なる真理表がありうるが、本モジュールはその双方を扱う。Perl の列では F は false または undefined (未定義)を意味する。Math::Logic の下では T, F, U はそれぞれ 1 (TRUE), 0 (FALSE), -1 (UNDEF) を意味するオブジェクトである。記号 + は伝播する null を意味する。

    Perl  Logic         Perl  Logic         Perl  Logic 
A B and  and+ and    A B or or+  or    A B xor  xor+ xor(same)
- - ---  ---  ---    - - -- --   --    - - ---  ---  ---
U U  F    U    U     U U  F  U    U    U U  F    U    U 
U F  F    U    F     U F  F  U    U    U F  F    U    U 
F U  F    U    F     F U  F  U    U    F U  F    U    U 
F F  F    F    F     F F  F  F    F    F F  F    F    F
U T  F    U    U     U T  T  U    T    U T  T    U    U
T U  F    U    U     T U  T  U    T    T U  T    U    U
T T  T    T    T     T T  T  T    T    T T  F    F    F
T F  F    F    F     T F  T  T    T    T F  T    T    T
F T  F    F    F     F T  T  T    T    F T  T    T    T

  Perl  Logic
A not  not+ not(same)
- ---  ---  ---
U  T    U    U
U  T    U    U
F  T    T    T
T  F    F    F

# 3値論理 (非伝播)
my $true   = Math::Logic->new( -value => $TRUE,  -degree => 3 ) ;
my $false  = Math::Logic->new( -value => $FALSE, -degree => 3 ) ;
my $undef  = Math::Logic->new( -value => $UNDEF, -degree => 3 ) ;

my $result = $undef & $false ; # my $result = $undef->and( $false ) ;

print $result if $result == $FALSE ; 

# 3値論理 (伝播)
my $true   = Math::Logic->new( -value => $TRUE,  -degree => 3, -propagate => 1 ) ;
my $false  = Math::Logic->new( -value => $FALSE, -degree => 3, -propagate => 1 ) ;
my $undef  = Math::Logic->new( -value => $UNDEF, -degree => 3, -propagate => 1 ) ;

my $result = $undef & $false ; # my $result = $undef->and( $false ) ;

print $result if $result == $UNDEF ; 

多値論理

 これはファジーロジックで利用される。典型的には 100%が true を、0% が false を表し、間の整数は確率を表すよう、-degree を 100 に設定する。
 多値論理における真理表は以下のようになる。

and     結果の最小値
or      結果の最高値
xor     真理表 xor(a,b) == and(or(a,b),not(and(a,b)))
not     degree - 結果値

           Logic
 A   B  and  or xor
--- --- --- --- ---
  0   0   0   0   0
  0 100   0 100 100
100   0   0 100 100
100 100 100 100   0
  0  33   0  33  33
 33   0   0  33  33
 33 100  33 100  67
 33  33  33  33  33
100  33  33 100  67
  0  67   0  67  67
 67   0   0  67  67
 67 100  67 100  33
 67  67  67  67  33
100  67  67 100  33
 33  67  33  67  67
 67  33  33  67  67

 A  not
--- ---
  0 100
 33  67
 67  33
100   0

# 多値論理
my $True   = 100 ; # 独自の TRUE 及び FALSE を定義
my $False  = $FALSE ;
$true      = Math::Logic->new( -value => $True,  -degree => $True ) ;
$very      = Math::Logic->new( -value => 67,     -degree => $True ) ;
$fairly    = Math::Logic->new( -value => 33,     -degree => $True ) ;
$false     = Math::Logic->new( -value => $False, -degree => $True ) ;

my $result = $fairly & $very ; # my $result = $fairly->and( $very ) ;

print $result if $result == $fairly ; 

パブリックメソッド

new             class   object (割り当てにも使用可能)
new_from_string class   object
value                   object
degree                  object
propagate               object
incompatible            object
compatible              object (廃止の可能性)
as_string               object 
and                     object (& と同様)
or                      object (| と同様)
xor                     object (^ と同様)
not                     object (! と同様)
""                      object (as_string を見よ)
0+                      object (自動的に処理)
<=>                     object (比較)
&                       object (論理的 and)
|                       object (論理的 or)
^                       object (論理的 xor)
!                       object (論理的 not)

new (クラスメソッド/オブジェクトメソッド)

my $x = Math::Logic->new ;

my $y = Math::Logic->new( -value => $FALSE, -degree => 3, -propagate => 0 );

my $a = $x->new ; 

my $b = $y->new( -value => $TRUE ) ;

 新しい Math::Logic オブジェクトを生成する。new はどのような引数が渡されても落ちてはならない。特に2値または多値論理で値が -1 (UNDEF) に設定されたら、黙って 0 (FALSE) に変換される。それ以外の場合は、Perl における true を 1 (TRUE) に変換し、そうでなければ 0 (FALSE) に変換する。
 オブジェクトメソッドとして利用した場合、上書きされっるまではオリジナルのオブジェクトの設定値はそのままである。もしクラスメソッドとして引数なしで利用さえれればデフォルト値が設定される。
 -degree は可能な真理値を示す整数であり、典型的には 2, 3 または 100(パーセンテージを示す)に設定される。最小値は 2 である。
 -propagate は NULL (UNDEF) が伝播させるか否かを指定する true/false の整数値である。真理表が使われる3値論理にのみ適用可能である。
 -value は真理値を示す整数である。2値論理の場合には 1 及び 0 のみが妥当であり(TRUE 及び FALSE)、3値論理の場合には 1, 0, -1 のみが妥当である(TRUE, FALSE, UNDEF)。多値論理の場合は -degree 以下の正の整数が妥当である。

new_from_string (クラスメソッド/オブジェクトメソッド)

my $x = Math::Logic->new_from_string( '1,2' ) ;
my $y = Math::Logic->new_from_string( 'TRUE,3,-propagate' ) ;
my $z = Math::Logic->new_from_string( '( FALSE, 3, -propagate )' ) ;
my $m = Math::Logic->new_from_string( '33,100' ) ;
my $n = Math::Logic->new_from_string( '67%,100' ) ;

 新しい Math::Logic オブジェクトを生成する。文字列には最初の2つの文字列-value 及び -degree が含まれなければならない。
 True は 1, T または例えば TRUE や -true などの T で始まる言葉で表現される。パターンは /^-?[tT]/ である。
 False は 0, F または例えば FALSE や -false などの F で始まる言葉で表現される。パターンは /^-?[fF]/ である。
 Undef は -1, U または例えば UNDEF や -undef などの U で始まる言葉で表現される。パターンはs /^-?[uU]/ である。
 Propagate を true に設定するには /^-?[tTpP1]/ に適合するような3つめのパラメータとして例えば -propagate のように設定する。propagate を false に設定するためには3つめのパラメータを設定しないか、0 (zero) を含むことである。

value  (オブジェクトメソッド)

print $x->value ;
print $x ;

 オブジェクトの数値を返す。2値論理の場合は常に 1 または 0 であり、3値論理の場合は 1, 0, -1 であり、多値論理の場合は -degree 以下の正の整数である。

degree (オブジェクトメソッド)

print $x->degree ;

 オブジェクトの次数を返す。すなわちオブジェクトが保持可能な真理値の値である。常に2以上である。.

propagate (オブジェクトメソッド)

print $x->propagate ;

 オブジェクトが NULL (UNDEF) を伝播させるか否かを返す。2値または多値論理では常に FALSE であり、3値論理では TRUE または FALSE を返す。

incompatible (オブジェクトメソッド)

print $x & $y unless $x->incompatible( $y ) ; 

 オブジェクトが互換なら FALSE を返す。非互換なら(Perl が True として扱えば)エラーメッセージを返す。例えば

$x = Math::Logic->new_from_string('1,2') ;
$y = Math::Logic->new_from_string('0,3') ;

# 上記は、1行目は2値論理であり、2行目は3値論理であるので互換ではない。
print $x->incompatible( $y ) if $x->incompatible( $y ) ;

# これは以下のような出力を出す。ike:
Math::Logic(2,0) and Math::Logic(3,0) are incompatible at ./logic.t line 2102
# 最初の値は次数で、2番めの値は伝播の設定

 同じ -degree ならばオブジェクトは互換で、3値論理の場合は同じ -propagate なら互換である。論理演算子は互換なオブジェクト間でのみ機能し、強制変換はしない。(ただしタイプキャスティングを見よ)

compatible;廃止予定 (オブジェクトメソッド)

print $x->compatible( $y ) ;

 2つのオブジェクトが互換であるか否かで TRUE または FALSE を返す。
 同じ -degree ならばオブジェクトは互換で、3値論理の場合は同じ -propagate なら互換である。論理演算子は互換なオブジェクト間でのみ機能し、強制変換はしない。(ただしタイプキャスティングを見よ)

as_string 及び "" (オブジェクトメソッド)

                                # output:
print $x->as_string ;           # TRUE
print $x->as_string( 1 ) ;      # (TRUE,2)
print $x->as_string( -full ) ;  # (TRUE,2)

print $x ;                      # TRUE
print $x->value ;               # 1

print $m ;                      # 33
print $m->value ;               # 33
print $m->as_string( 1 ) ;      # (33%,100)

 必要になれば Perl が要求するので普段は as_string を使うのに困ることはないだろう。しかしながら保存できる文字列が欲しければ(おそらく後で new_from_string で読みたいとき)、as_string に引数として渡せばよい。

and 及び &  (オブジェクトメソッド)

print "true" if ( $y & $z ) == $TRUE ;
print "yes"  if $y & 1 ;
print "yes"  if $TRUE & $y ;

$r = $y & $z ; # 結果の真理値とともに新しい Math::Logic オブジェクトを生成

print "true" if $y->and( $z ) == $TRUE ;

 2つのオブジェクトに対し論理的 and を適用する。真理表はオブジェクトの -degree 値(3値論理の場合には -propagate)により使用される。(上記の真理表を見よ)

or 及び | (オブジェクトメソッド)

print "true" if ( $y | $z ) == $TRUE ;
print "yes"  if $y | 1 ;
print "yes"  if $TRUE | $y ;

$r = $y | $z ; # 結果の真理値とともに新しい Math::Logic オブジェクトを生成

print "true" if $y->or( $z ) == $TRUE ;

 2つのオブジェクトに対し論理的 or を適用する。真理表はオブジェクトの -degree 値(3値論理の場合には -propagate)により使用される。(上記の真理表を見よ)

xor 及び ^ (オブジェクトメソッド)

print "true" if ( $y ^ $z ) == $TRUE ;
print "yes"  if $y ^ 0 ;
print "yes"  if $TRUE ^ $y ;

$r = $y ^ $z ; # 結果の真理値とともに新しい Math::Logic オブジェクトを生成

print "true" if $y->xor( $z ) == $TRUE ;

 2つのオブジェクトに対し論理的 xor を適用する。真理表はオブジェクトの -degree 値により使用される。(上記の真理表を見よ)

not 及び ! (オブジェクトメソッド)

print "true" if ! $y == $TRUE ;

$r = ! $y ; # 結果の真理値とともに新しい Math::Logic オブジェクトを生成

print "true" if $y->not == $TRUE ;

 オブジェクトに論理的 not を適用する。真理表はオブジェクトの -degree 値により使用される。(上記の真理表を見よ)

compatible 及び <=> (オブジェクトメソッド)

 標準の(数値に対する)比較演算子(<, <=, >, =>, ==, !=, <=>)を Math::Logic オブジェクトにも適用する。

タイプキャスティング

 2値論理と3値論理の間でしか意味を持たない、タイプキャスティングを行う。これは直接サポートはしていないが、以下のように実行される。

my $x = Math::Logic->new_from_string( '1,2' ) ;  # TRUE  2値
my $y = Math::Logic->new_from_string( '0,3' ) ;  # FALSE 3値
my $z = Math::Logic->new_from_string( '-1,3' ) ; # UNDEF 3値

$x3 = $x->new( -degree => 3 ) ;
$y2 = $y->new( -degree => 2 ) ;
$z2 = $y->new( -degree => 2 ) ; # UNDEF は黙って FALSE に変換

バグ

 多値論理の最小次数は 4。すなわち5値。0..4.
 2つの互換でない Math::Logic オブジェクトを & でつなぐと Perl は落ちる。これはオーバーロードのせいではないと信じている。Perl 5.6.0 では起きない。


変更

2000/05/25

 変更なし。パーミッションの問題でテストが失敗することがないよう圧縮ファイル内のエラーを変更したのみ。

2000/05/22

 読み取り専用の問題を解消。

2000/04/26

 内部エラーチェックを大量に削除し、速度が改善。
 クラスは継承可能。

2000/04/15

 読み込み専用スカラを定数に変更。TRUE の代わりに $TRUE とした。
 これはある種の場合には有効である。例えば文字列解釈は配列の添数やハッシュキーに用いることができる。(今は使われない)定数はまだ使えるが、定数スカラを代わりに使うことを推奨する。Math::Logic を利用するときにいつでも使いたいのであれば readonly.pm をインストールする必要がある。
 オーバーロードに関するバグは Perl 5.6.0 では起きない。Perl のバージョンが 5.005 以降であればテストはうまく行くテストを2つ追加。

2000/02/27

 用語を明確化してドキュメントをマイナー変更。
 2つのバグを追記。
 テストを追加。

2000/02/23

 多値論理での xor を真理値のものと等価に。すなわち

xor(a,b) == and(or(a,b),not(and(a,b)))

 Math::Logic では以下のように表現されていた。

$a->xor( $b ) == $a->or( $b )->and( $a->and( $b )->not )

または

$a ^ $b == ( $a | $b ) & ( ! ( $a & $b ) )
2000/02/22

 エラーメッセージでファイル名や行を2回表示しないように _croak を改良。その他エラーメッセージを改良。
 new_from_string が文字列の真理値を扱えるように変更。数値の真理値も以前のように扱える。

2000/02/21

非互換で、今は使わないメソッドを追加。これでエラーメッセージを改良。テスト用スクリプトを改良。

2000/02/20

 ドキュメントのマイナー変更。5.005 で表示される警告を出ないようにした。

2000/02/19

 最初のバージョン。Math::Logic3 及び(未発表の)Math::Fuzzy からアイデアをとった。本モジュールは両者の後継を意図している。


著者

 Mark Summerfield. <summer@perlpress.com> でコンタクトが取れるが、サブジェクトに 'logic' という単語を含んでほしい。


著作権

 Copyright (c) Mark Summerfield 2000. All Rights Reserved.

 本モジュールは LGPL の下で利用/配布/修正してもよい。


【訳注と解説】

  1. 上記文章で何度か「伝播」という言葉が出てくるが、これは特に3値論理の場合に、NULL や Unknown の存在を認めると、それが含まれる演算・処理の結果は基本として NULL になってしまう。1つの NULL の存在が広く影響を拡大してしまうことになる。これを「NULL の伝播」ということがある。これをそのまま伝播させておくか否かを設定しておくというわけである。
Toolbox Logo
Updated : 2006/10/11