NAME

Math::Logic - Provides pure 2, 3 or multi-value logic.

SYNOPSIS

	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-value logic
    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-value logic (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-value logic (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 ;

    # multi-value logic
    my $TRUE   = 100 ; # Define our own true
    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 ;

DESCRIPTION

Perl's built-in logical operators, and, or, xor and not support 2-value logic. This means that they always produce a result which is either true or false. In fact perl sometimes returns 0 and sometimes returns undef for false depending on the operator and the order of the arguments. For "true" Perl generally returns the first value that evaluated to true which turns out to be extremely useful in practice. Given the choice Perl's built-in logical operators are to be preferred -- but when you really want pure 2-value logic or 3-value logic or multi-value logic they are available through this module.

The only 2-value logic values are 1 (TRUE) and 0 (FALSE).

The only 3-value logic values are 1 (TRUE), 0 (FALSE) and -1 (UNDEF). Note that UNDEF is -1 not undef!

The only multi-value logic values are 0 (FALSE)..-degree -- the value of TRUE is equal to the degree, usually 100.

Although some useful constants may be exported, this is an object module and the results of logical comparisons are Math::Logic objects.

2-value logic

2-value logic has one simple truth table for each logical operator.

    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

In the above tables when dealing with Perl's built-in logic T and F are any true and any false value respectively; with Math::Logic they are objects whose values are 1 and 0 respectively. Note that whilst Perl may return 0 or undef for false and any other value for true, Math::Logic returns an object whose value is either 0 (FALSE) or 1 (TRUE) only.

 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-value logic

3-value logic has two different truth tables for "and" and "or"; this module supports both. In the Perl column F means false or undefined; and T, F and U under Math::Logic are objects with values 1 (TRUE), 0 (FALSE) and -1 (UNDEF) respectively. The + signifies propagating nulls (UNDEFs).

    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-value logic (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 $result = $undef & $false ; # my $result = $undef->and( $false ) ;

print $result if $result == FALSE ; 

# 3-value logic (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 $result = $undef & $false ; # my $result = $undef->and( $false ) ;

print $result if $result == UNDEF ; 

multi-value logic

This is used in `fuzzy' logic. Typically we set the -degree to 100 representing 100% likely, i.e. true; 0 represents 0% likely, i.e. false, and any integer in-between is a probability.

The truth tables for multi-value logic work like this:

 C<and> lowest  value is the result;
 C<or>  highest value is the result;
 C<xor> highest value is the result 
        unless they're the same in which case the result is FALSE;
 C<not> degree minus the value is the result.

            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  33
  33  33  33  33   0
 100  33  33 100 100
   0  67   0  67  67
  67   0   0  67  67
  67 100  67 100 100
  67  67  67  67   0
 100  67  67 100 100
  33  67  33  67  67
  67  33  33  67  67

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

 # multi-value logic
 my $TRUE   = 100 ; # Define our own TRUE and 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 ; 

Public methods

new             class   object (also used for assignment)
new_from_string class   object
value                   object
degree                  object
propagate               object
compatible              object
as_string               object 
and                     object (same as &)
or                      object (same as |)
xor                     object (same as ^)
not                     object (same as !)
""                      object (see as_string)
0+                      object (automatically handled)
<=>                     object (comparisons)
&                       object (logical and)
|                       object (logical or)
^                       object (logical xor)
!                       object (logical 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 ) ;

This creates new Math::Logic objects. new should never fail because it will munge any arguments into something `sensible'.

If used as an object method, e.g. for assignment then the settings are those of the original object unless overridden. If used as a class method with no arguments then default values are used.

-degree an integer indicating the number of possible truth values; typically set to 2, 3 or 100 (to represent percentages). Minimum value is 2.

-propagate a true/false integer indicating whether NULLs (UNDEF) should propagate; only applicable for 3-value logic where it influences which truth table is used.

-value an integer representing the truth value. For 2-value logic only 1 and 0 are valid (TRUE and FALSE); for 3-value logic 1, 0, and -1 are valid (TRUE, FALSE and UNDEF); for multi-value logic any positive integer less than or equal to the -degree is valid.

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' ) ;

This creates new Math::Logic objects. The string must include the first two values, which are -value and -degree respectively.

value

print $x->value ;
print $x ;

This returns the numeric value of the object. For 2-value logic this will always be 1 or 0; for 3-value logic the value will be 1, 0 or -1; for multi-value logic the value will be a positive integer <= -degree.

degree

print $x->degree ;

This returns the degree of the object, i.e. the number of possible truth values the object may hold; it is always 2 or more.

propagate

print $x->propagate ;

This returns whether or not the object propagates NULLs (UNDEF). Objects using 2 or multi-value logic always return FALSE; 3-value logic objects may return TRUE or FALSE.

compatible

print $x->compatible( $y ) ;

Returns TRUE or FALSE depending on whether the two objects are compatible. Objects are compatible if they have the same -degree and in the case of 3-value logic the same -propagate. Logical operators will only work on compatible objects, there is no type-coersion (but see typecasting later).

as_string and "" # 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)

Usually you won't have to bother using as_string since Perl will invoke it for you as necessary; however if you want a string that can be saved, (perhaps to be read in using new_from_string later), you can pass an argument to as_string.

and and &

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

$r = $y & $z ; # Creates a new Math::Logic object with the resultant truth value

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

Applies logical and to two objects. The truth table used depends on the object's -degree (and in the case of 3-value logic on the -propagate). (See the truth tables above.)

or and |

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

$r = $y | $z ; # Creates a new Math::Logic object with the resultant truth value

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

Applies logical or to two objects. The truth table used depends on the object's -degree (and in the case of 3-value logic on the -propagate). (See the truth tables above.)

xor and ^

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

$r = $y ^ $z ; # Creates a new Math::Logic object with the resultant truth value

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

Applies logical xor to two objects. The truth table used depends on the object's -degree. (See the truth tables above.)

not and !

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

$r = ! $y ; # Creates a new Math::Logic object with the resultant truth value

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

Applies logical not to the object. The truth table used depends on the object's -degree. (See the truth tables above.)

comparisons and <=>

All the standard (numeric) comparison operators may be applied to Math::Logic objects, i.e. <, <=, >, =>, ==, != and <=>.

typecasting

The only typecasting that appears to make sense is between 2 and 3-value logic. There is no direct support for it but it can be achieved thus:

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

$x3 = $x->new( -degree => 3 ) ;
$y2 = $y->new( -degree => 2 ) ;
$z2 = $y->new( -degree => 2 ) ; # UNDEF converted silently to FALSE

BUGS

(none known)

CHANGES

2000/02/20

Minor documentation fixes. Also eliminated a warning that occurred under 5.005.

2000/02/19

First version. Ideas taken from my Math::Logic3 and (unpublished) Math::Fuzzy; this module is intended to supercede both.

AUTHOR

Mark Summerfield. I can be contacted as <summer@perlpress.com> - please include the word 'logic' in the subject line.

COPYRIGHT

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

This module may be used/distributed/modified under the LGPL.