Logical operations

From Rosetta Code
Task
Logical operations
You are encouraged to solve this task according to the task description, using any language you may know.

Basic Data Operation
This is a basic data operation. It represents a fundamental action on a basic data type.

You may see other such operations in the Basic Data Operations category, or:

Integer Operations
Arithmetic | Comparison

Boolean Operations
Bitwise | Logical

String Operations
Concatenation | Interpolation | Comparison | Matching

Memory Operations
Pointers & references | Addresses

Write a function that takes two logical (boolean) values, and outputs the result of "and" and "or" on both arguments as well as "not" on the first arguments. If the programming language doesn't provide a separate type for logical values, use the type most commonly used for that purpose.

If the language supports additional logical operations on booleans such as XOR, list them as well.

Ada

I have also included logical xor because it is defined for Ada boolean types. All the operators below work equally well on arrays of boolean types. In fact, a packed array of boolean is an array of bits, providing a direct link between logical and bitwise operations.

procedure Print_Logic(A : Boolean; B : Boolean) is
begin
   Put_Line("A and B is " & Boolean'Image(A and B));
   Put_Line("A or B  is " & Boolean'Image(A or B));
   Put_Line("A xor B is " & Boolean'Image(A xor B));
   Put_Line("not A   is " & Boolean'Image(not A));
end Print_Logic;

ALGOL 68

PROC print_logic = (BOOL a, b)VOID:
(
# for a 6-7 bit/byte compiler #
  printf(($"a and b is "gl$, a AND b);
  printf(($"a or b is "gl$, a OR b);
  printf(($"not a is "gl$, NOT a);
  printf(($"a equivalent to b is "gl$, a EQ b);
  printf(($"a not equivalent to b is "gl$, a NE b);

# Alternatively ASCII # 
  printf(($"a and b is "gl$, a & b); 
  printf(($"a and b is "gl$, a /\ b);  
  printf(($"a or b is "gl$, a \/ b);
  printf(($"a equivalent to b "gl$, a = b);
  printf(($"a not equivalent to b "gl$, a /= b);

¢ for a European 8 bit/byte charcter set eg. ALCOR or GOST ¢
  printf(($"a and b is "gl$, a ∧ b);
  printf(($"a or b is "gl$, a ∨ b);
  printf(($"not a is "gl$, ¬ a)
  printf(($"a not equivalent to b is "gl$, a ≠ b)
)

AWK

<lang awk> $ awk '{print "and:"($1&&$2),"or:"($1||$2),"not:"!$1}' 0 0 and:0 or:0 not:1 0 1 and:0 or:1 not:1 1 0 and:0 or:1 not:0 1 1 and:1 or:1 not:0</lang>

BASIC

Works with: QuickBasic version 4.5
SUB logic (a%, b%) 'no booleans in BASIC...these are integers. 1 for true 0 for false.
  PRINT a AND b
  PRINT a OR b
  PRINT NOT a
END SUB

C

<lang c>void print_logic(int a, int b) {

 printf("a and b is %d\n", a && b);
 printf("a or b is %d\n", a || b);
 printf("not a is %d\n", !a);

}</lang>

C++

<lang cpp>void print_logic(bool a, bool b) {

 std::cout << std::boolalpha; // so that bools are written as "true" and "false"
 std::cout << "a and b is " << (a && b) << "\n";
 std::cout << "a or b is " << (a || b) << "\n";
 std::cout << "not a is " << (!a) << "\n";

}</lang>

ColdFusion

<cffunction name = "logic" hint = "Performs basic logical operations">
  <cfargument name = "a" required = "yes" type = "boolean" />
  <cfargument name = "a" required = "yes" type = "boolean" />
  <cfoutput>
    'A' AND 'B' is #a AND b#< br />
    'A' OR  'B' is #a OR  b#< br />
    NOT 'A'     is #!a#
  </cfoutput>
</cffunction>

Common Lisp

<lang lisp>(defun logic (a b)

 (print "a and b is") (write (and a b))
 (print "a or b is" ) (write (or a b))
 (print "not a is"  ) (write (not a)))</lang>

D

<lang d>module andOr ; import std.stdio ;

void logic(T,U)(T lhs, U rhs){

 writefln("'%s' is of type '%s', '%s' is of type '%s';", 
   lhs,typeid(typeof(lhs)), rhs,typeid(typeof(rhs))) ;
 writefln("\t'%s' AND '%s' is %s, ", lhs, rhs, lhs && rhs) ;
 writefln("\t'%s' OR '%s' is %s, ", lhs, rhs, lhs || rhs) ;
 writefln("\tNOT '%s' is %s.\n", lhs, !lhs) ;

}

class C {int value ; }

void main() {

 bool theTruth = true ;
 bool theLie = false ;
 real zeroReal = 0.0L ;
 real NaN ; // D init. float type to NaN ;
 int zeroInt  = 0 ;
 real[] nullArr = null ;
 string emptyStr = "" ;
 string nullStr = null ;
 C someC = new C ;
 C nullC = null ;
 //Note: Struct is value type in D, but composite so no default bool equivalent  
 logic(theTruth, theLie) ; 
 logic(zeroReal, NaN) ;  
 logic(zeroInt, nullArr) ; 
 logic(nullStr, emptyStr) ;  
 logic(someC, nullC) ;  

}</lang>

E

<lang e>def logicalOperations(a :boolean, b :boolean) {

   return ["and" => a & b,
           "or"  => a | b,
           "not" => !a,
           "xor" => a ^ b]

}</lang>

Each of these is a method on boolean objects; the above is precisely equivalent to:

<lang e>def logicalOperations(a :boolean, b :boolean) {

   return ["and" => a.and(b),
           "or"  => a.or(b),
           "not" => a.not(),
           "xor" => a.xor(b)]

}</lang>

If the :boolean guards were removed, these operations would also work on other types, such as sets (& is union and | is intersection; not is not supported).

FALSE

FALSE uses zero/non-zero for testing False and True. Comparison operators return -1 for True and 0 for False, which work with bitwise operators for logical operations.

1 3=~["unequal, "]?
1 1= 1_=["true is -1, "]?
0~["false is 0, "]?
'm$'a>'z@>&["a < m < z"]?

Forth

Forth can use bitwise operators if the boolean values are well formed: TRUE (-1) and FALSE (0). 0<> converts an ill-formed flag (zero/non-zero) to a well-formed flag (false/true).

: .bool ( ? -- ) if ." true" else ." false" then ;
: logic ( a b -- ) 0<> swap 0<> swap
 cr ." a = " over .bool ."   b = " dup .bool
 cr ." a and b = " 2dup and .bool
 cr ." a  or b = " over  or .bool
 cr ." not a = " 0= .bool ;

Fortran

In ANSI FORTRAN 66 or later, use LOGICAL data type: <lang fortran> SUBROUTINE PRNLOG(A, B)

      LOGICAL A, B
      PRINT *, 'a and b is ', A .AND. B
      PRINT *, 'a or b is ', A .OR. B
      PRINT *, 'not a is ', .NOT. A
      

C You did not ask, but the following logical operators are also standard C since ANSI FORTRAN 66 C =======================================================================

C This yields the same results as .EQ., but has lower operator precedence C and only works with LOGICAL operands:

      PRINT *, 'a equivalent to b is ', A .EQV. B
      

C This yields the same results as .NE., but has lower operator precedence C and only works with LOGICAL operands (this operation is also commonly C called "exclusive or"):

      PRINT *, 'a not equivalent to b is ', A .NEQV. B
      END</lang>

Groovy

<lang groovy>def logical = { a, b ->

   println """

a AND b = ${a} && ${b} = ${a & b} a OR b = ${a} || ${b} = ${a | b} NOT a = ! ${a} = ${! a} a XOR b = ${a} != ${b} = ${a != b} a EQV b = ${a} == ${b} = ${a == b} """ }</lang>

Program: <lang groovy>logical(true, true) logical(true, false) logical(false, false) logical(false, true)</lang>

Output:

a AND b   = true && true   = true
a OR b    = true || true   = true
NOT a     = ! true         = false
a XOR b   = true != true   = false
a EQV b   = true == true   = true


a AND b   = true && false   = false
a OR b    = true || false   = true
NOT a     = ! true         = false
a XOR b   = true != false   = true
a EQV b   = true == false   = false


a AND b   = false && false   = false
a OR b    = false || false   = false
NOT a     = ! false         = true
a XOR b   = false != false   = false
a EQV b   = false == false   = true


a AND b   = false && true   = false
a OR b    = false || true   = true
NOT a     = ! false         = true
a XOR b   = false != true   = true
a EQV b   = false == true   = false

Haskell

Instead of a function and printing, which is unidiomatic for Haskell, here are the operations in the same style as in Bitwise operations:

a = False
b = True

a_and_b = a && b
a_or_b  = a || b
not_a   = not a

Io

printLogic := method(a,b,
  writeln("a and b is ", a and b)
  writeln("a or b is ", a or b)
  writeln("not a is ", a not) 
)

J

J uses 0 for logical false and 1 for logical true.

aon=: *. , +. , -.@[

The verb defined above is unidiomatic in that when arrays are provided as arguments the results don't seem useful. Definition as seen in the Haskell example would be more natural.

Additional primary logical operators are *: (not-and), +: (not-or), ~: (exclusive-or).

An example more closely following the others on this page (J is interactive so indented lines are user-entered and lines flush left are system outputs):

   and=: *.
   or=: +.
   not=: -.
   a=. 0 0 1 1   NB. Work on vectors to show all possible
   b=. 0 1 0 1   NB. 2-bit combos at once.
   (a and b),(a or b),:not a
0 0 0 1
0 1 1 1
1 1 0 0

Java

<lang java>public static void logic(boolean a, boolean b){

 System.out.println("a AND b: " + (a && b));
 System.out.println("a OR b: " + (a || b));
 System.out.println("NOT a: " + (!a));

}</lang>

Additionally, ^ is used for XOR and == is used for "equal to" (a.k.a. bidirectional implication).

JavaScript

<lang javascript>function logic(a,b) {

 print("a AND b: " + (a && b));
 print("a OR b: " + (a || b));
 print("NOT a: " + (!a));

}</lang>

The boolean literals are used as words ("true and "false) when used in a program.

to logic :a :b
  (print [a AND b =] and :a :b)
  (print [a OR b =] or :a :b)
  (print [NOT a =] not :a)
end

AND and OR may have arity greater than two if used in parentheses (and :a :b :c).

MAXScript

fn printLogic a b =
(
    format "a and b is %\n" (a and b)
    format "a or b is %\n" (a or b)
    format "not a is %\n" (not a)
)

Metafont

<lang metafont>def tf(expr a) = if a: "true" else: "false" fi enddef; def test(expr a, b) =

 for o = "and", "or":
   message tf(a) & " " & o & " " & tf(b);
   show a scantokens(o) b;
 endfor
 message "not " & tf(a);
 show not a enddef;</lang>

<lang metafont>test(true, true); test(false, false); test(true, false); test(false, true); end</lang>

Modula-3

MODULE Logical EXPORTS Main;

FROM IO IMPORT Put;
FROM Fmt IMPORT Bool;

PROCEDURE Test(a, b: BOOLEAN) =
  BEGIN
    Put("a AND b is " & Bool(a AND b) & "\n");
    Put("a OR b is " & Bool(a OR b) & "\n");
    Put("NOT a is " & Bool(NOT a) & "\n");
  END Test;

BEGIN
  Test(TRUE, FALSE);
END Logical.

OCaml

<lang ocaml>let print_logic a b =

 Printf.printf "a and b is %B\n" (a && b);
 Printf.printf "a or b is %B\n" (a || b);
 Printf.printf "not a is %B\n" (not a)</lang>

Octave

<lang octave>function test(a, b)

 s1 = num2str(a);
 s2 = num2str(b);
 disp(strcat(s1, " and ", s2, " = ", num2str(a&&b)));
 disp(strcat(s1, " or ", s2, " = ", num2str(a||b)));
 disp(strcat("not ", s1, " = ", num2str(!a)));

endfunction

% constant true is 1, false is 0 test(true, true); test(false, false); test(true, false); test(false, true);</lang>

Pascal

<lang pascal> procedure printlogic(a, b: boolean);

begin
 writeln('a and b is ', a and b);
 writeln('a or b is ', a or b);
 writeln('not a is', not a);
end;

</lang>

Perl

<lang perl>sub print_logic {

       my ($a, $b)=@_;
       print "a and b is ${\($a && $b)}\n";
       print "a or b is ${\($a || $b)}\n";
       print "not a is ${\( ! $a)}\n";

}</lang>

PHP

<lang php>function print_logic($a, $b) {

   echo "a and b is ", $a && $b ? 'True' : 'False', "\n";
   echo "a or b is ", $a || $b ? 'True' : 'False', "\n";
   echo "not a is ", ! $a ? 'True' : 'False', "\n";

}</lang>

Pop11

define print_logic(a, b);
    printf(a and b, 'a and b is %p\n');
    printf(a or b, 'a or b is %p\n');
    printf(not(a), 'not a is %p\n');
enddefine;

Example usage is:

print_logic(true, false);

Python

<lang python>def logic(a, b):

       print 'a and b:', a and b
       print 'a or b:' , a or b
       print 'not a:'  , not a</lang>

Ruby

<lang ruby>def logic(a, b)

       print 'a and b: ', a && b, "\n"
       print 'a or b: ' , a || b, "\n"
       print 'not a: '  , !a    , "\n"

end</lang> and/or/not are synonymous with &&/||/! albeit with lower precedence.

Scheme

<lang scheme>(define (logic a b)

 (display "a and b is ")
 (display (and a b))
 (newline)
 (display "a or b is ")
 (display (or a b))
 (newline)
 (display "not a is ")
 (display (not a))
 (newline))</lang>

Slate

<lang slate>
</lang>


Smalltalk

Works with: GNU Smalltalk

<lang smalltalk>|test| test := [ :a :b |

 ('%1 %2 %3 = %4' % { a. 'and'. b. (a & b) }) displayNl.
 ('%1 %2 %3 = %4' % { a. 'or'. b. (a | b) }) displayNl.
 ('%1 %2 = %3' % {'not'. a. (a not) }) displayNl

].

test value: true value: true. test value: false value: false. test value: true value: false. test value: false value: true.</lang>

Standard ML

<lang sml>fun print_logic (a, b) = (

 print ("a and b is " ^ Bool.toString (a andalso b) ^ "\n");
 print ("a or b is " ^ Bool.toString (a orelse b) ^ "\n");
 print ("not a is " ^ Bool.toString (not a) ^ "\n")

)</lang>

Tcl

<lang tcl>proc logic {a b} {

   puts "a and b: [expr {$a && $b}]"
   puts "a or b:  [expr {$a || $b}]"
   puts "not a:   [expr {!$a}]"

}</lang>

Toka

This is an adaption of the code from the Forth example. Toka provides TRUE/FALSE flags that are the same as the well-formed flags in Forth.

 [ 0 <> [ ." true" ] [ ." false"] ifTrueFalse ] is .bool
 [ ( a b -- )
   cr ." a = " over .bool ."   b = " dup .bool
   cr ." a and b = " 2dup and .bool
   cr ." a  or b = " over  or .bool
   cr ." not a = " 0 = .bool
 ] is logic

V

Using stack shuffles.

[mylogic
  [get2 [dup] dip swap [dup] dip].
   get2 and puts
   get2 or puts
   swap not puts
   pop
 ].

Using view.

[mylogic
   [get2 [a b : a b a b] view].
   get2 and puts
   get2 or puts
   swap not puts
   pop
 ].

Using internal defines

[mylogic [a b] let
  a b and puts
  a b or puts
  a not puts
].

Visual Basic .NET

 Function Test(ByVal a As Boolean, ByVal b As Boolean)
     Console.WriteLine("And " & a And b)
     Console.WriteLine("Or " & a Or b)
     Console.WriteLine("Not " & Not a)
     Console.WriteLine("Xor " & a Xor b)
     Console.WriteLine("And, short-circuited " & a AndAlso b)
     Console.WriteLine("Or, short-circuited " & a OrElse b)
 End Function

XSLT

<xsl:template name="logic">
  <xsl:param name="a" select="true()"/>
  <xsl:param name="b" select="false()"/>
  <fo:block>a and b = <xsl:value-of select="$a and $b"/></fo:block>
  <fo:block>a or b = <xsl:value-of select="$a or $b"/></fo:block>
  <fo:block>not a = <xsl:value-of select="not($a)"/></fo:block>
</xsl:template>