Ternary logic: Difference between revisions

Content added Content deleted
m (syntax highlighting fixup automation)
Line 95: Line 95:


=={{header|Action!}}==
=={{header|Action!}}==
<lang Action!>DEFINE TERNARY="BYTE"
<syntaxhighlight lang="action!">DEFINE TERNARY="BYTE"
DEFINE FALSE="0"
DEFINE FALSE="0"
DEFINE MAYBE="1"
DEFINE MAYBE="1"
Line 192: Line 192:
OD
OD
OD
OD
RETURN</lang>
RETURN</syntaxhighlight>
{{out}}
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Ternary_logic.png Screenshot from Atari 8-bit computer]
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Ternary_logic.png Screenshot from Atari 8-bit computer]
Line 224: Line 224:


We first specify a package "Logic" for three-valued logic. Observe that predefined Boolean functions, "and" "or" and "not" are overloaded:
We first specify a package "Logic" for three-valued logic. Observe that predefined Boolean functions, "and" "or" and "not" are overloaded:
<lang Ada>package Logic is
<syntaxhighlight lang="ada">package Logic is
type Ternary is (True, Unknown, False);
type Ternary is (True, Unknown, False);


Line 238: Line 238:
function To_Ternary(B: Boolean) return Ternary;
function To_Ternary(B: Boolean) return Ternary;
function Image(Value: Ternary) return Character;
function Image(Value: Ternary) return Character;
end Logic;</lang>
end Logic;</syntaxhighlight>


Next, the implementation of the package:
Next, the implementation of the package:


<lang Ada>package body Logic is
<syntaxhighlight lang="ada">package body Logic is
-- type Ternary is (True, Unknown, False);
-- type Ternary is (True, Unknown, False);


Line 303: Line 303:
end Implies;
end Implies;


end Logic;</lang>
end Logic;</syntaxhighlight>


Finally, a sample program:
Finally, a sample program:
<lang Ada>with Ada.Text_IO, Logic;
<syntaxhighlight lang="ada">with Ada.Text_IO, Logic;


procedure Test_Tri_Logic is
procedure Test_Tri_Logic is
Line 340: Line 340:
Truth_Table(F => Equivalent'Access, Name => "Eq");
Truth_Table(F => Equivalent'Access, Name => "Eq");
Truth_Table(F => Implies'Access, Name => "Implies");
Truth_Table(F => Implies'Access, Name => "Implies");
end Test_Tri_Logic;</lang>
end Test_Tri_Logic;</syntaxhighlight>


{{out}}
{{out}}
Line 366: Line 366:
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
'''File: Ternary_logic.a68'''
'''File: Ternary_logic.a68'''
<lang algol68># -*- coding: utf-8 -*- #
<syntaxhighlight lang="algol68"># -*- coding: utf-8 -*- #


INT trit width = 1, trit base = 3;
INT trit width = 1, trit base = 3;
Line 464: Line 464:
#true # (false, maybe, true )
#true # (false, maybe, true )
)[@-1,@-1][INITINT a, INITINT b]
)[@-1,@-1][INITINT a, INITINT b]
);</lang>'''File: Template_operators_logical_mixin.a68'''
);</syntaxhighlight>'''File: Template_operators_logical_mixin.a68'''
<lang algol68># -*- coding: utf-8 -*- #
<syntaxhighlight lang="algol68"># -*- coding: utf-8 -*- #


OP & = (LOGICAL a,b)LOGICAL: a AND b;
OP & = (LOGICAL a,b)LOGICAL: a AND b;
Line 489: Line 489:
OP ~ = (LOGICAL a)LOGICAL: NOT a,
OP ~ = (LOGICAL a)LOGICAL: NOT a,
~= = (LOGICAL a,b)LOGICAL: a /= b; SCALAR!
~= = (LOGICAL a,b)LOGICAL: a /= b; SCALAR!
FI#</lang>'''File: test_Ternary_logic.a68'''
FI#</syntaxhighlight>'''File: test_Ternary_logic.a68'''
<lang algol68>#!/usr/local/bin/a68g --script #
<syntaxhighlight lang="algol68">#!/usr/local/bin/a68g --script #
# -*- coding: utf-8 -*- #
# -*- coding: utf-8 -*- #


Line 559: Line 559:
print trit op table("⊃","IMPLIES", (TRIT a,b)TRIT: a IMPLIES b);
print trit op table("⊃","IMPLIES", (TRIT a,b)TRIT: a IMPLIES b);
print trit op table("∧","AND", (TRIT a,b)TRIT: a AND b);
print trit op table("∧","AND", (TRIT a,b)TRIT: a AND b);
print trit op table("∨","OR", (TRIT a,b)TRIT: a OR b)</lang>
print trit op table("∨","OR", (TRIT a,b)TRIT: a OR b)</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 622: Line 622:
Arturo's '':logical'' values inherently support ternary logic (<code>true</code>, <code>false</code> and <code>maybe</code>) and the corresponding logical operations.
Arturo's '':logical'' values inherently support ternary logic (<code>true</code>, <code>false</code> and <code>maybe</code>) and the corresponding logical operations.


<lang rebol>vals: @[true maybe false]
<syntaxhighlight lang="rebol">vals: @[true maybe false]


loop vals 'v -> print ["NOT" v "=>" not? v]
loop vals 'v -> print ["NOT" v "=>" not? v]
Line 639: Line 639:
loop vals 'v2
loop vals 'v2
-> print [v1 "XOR" v2 "=>" xor? v1 v2]
-> print [v1 "XOR" v2 "=>" xor? v1 v2]
]</lang>
]</syntaxhighlight>


{{out}}
{{out}}
Line 679: Line 679:


=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
<lang AutoHotkey>Ternary_Not(a){
<syntaxhighlight lang="autohotkey">Ternary_Not(a){
SetFormat, Float, 2.1
SetFormat, Float, 2.1
return Abs(a-1)
return Abs(a-1)
Line 698: Line 698:
Ternary_Equiv(a,b){
Ternary_Equiv(a,b){
return a=b?1:a=1?b:b=1?a:0.5
return a=b?1:a=1?b:b=1?a:0.5
}</lang>
}</syntaxhighlight>
Examples:<lang AutoHotkey>aa:=[1,0.5,0]
Examples:<syntaxhighlight lang="autohotkey">aa:=[1,0.5,0]
bb:=[1,0.5,0]
bb:=[1,0.5,0]


Line 729: Line 729:
StringReplace, Res, Res, 0, false, all
StringReplace, Res, Res, 0, false, all
MsgBox % Res
MsgBox % Res
return</lang>
return</syntaxhighlight>
{{out}}
{{out}}
<pre> Ternary_Not true = false
<pre> Ternary_Not true = false
Line 778: Line 778:
=={{header|BASIC256}}==
=={{header|BASIC256}}==
{{trans|Liberty BASIC}}
{{trans|Liberty BASIC}}
<syntaxhighlight lang="lb">
<lang lb>
global tFalse, tDontKnow, tTrue
global tFalse, tDontKnow, tTrue
tFalse = 0
tFalse = 0
Line 849: Line 849:
end case
end case
end function
end function
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 857: Line 857:
=={{header|BBC BASIC}}==
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
{{works with|BBC BASIC for Windows}}
<lang bbcbasic> INSTALL @lib$ + "CLASSLIB"
<syntaxhighlight lang="bbcbasic"> INSTALL @lib$ + "CLASSLIB"
REM Create a ternary class:
REM Create a ternary class:
Line 902: Line 902:
PRINT "TRUE EQV TRUE = " FN(mytrit.teqv)("TRUE","TRUE")
PRINT "TRUE EQV TRUE = " FN(mytrit.teqv)("TRUE","TRUE")
PROC_discard(mytrit{})</lang>
PROC_discard(mytrit{})</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 937: Line 937:
=={{header|C}}==
=={{header|C}}==
===Implementing logic using lookup tables===
===Implementing logic using lookup tables===
<lang c>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>
typedef enum {
typedef enum {
Line 1,007: Line 1,007:
return 0;
return 0;
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 1,055: Line 1,055:


===Using functions===
===Using functions===
<lang c>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>


typedef enum { t_F = -1, t_M, t_T } trit;
typedef enum { t_F = -1, t_M, t_T } trit;
Line 1,090: Line 1,090:


return 0;
return 0;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>[Not]
<pre>[Not]
Line 1,131: Line 1,131:
the result is randomly sampled to true or false according to the chance.
the result is randomly sampled to true or false according to the chance.
(This description is definitely very confusing perhaps).
(This description is definitely very confusing perhaps).
<lang c>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>


Line 1,185: Line 1,185:


return 0;
return 0;
}</lang>
}</syntaxhighlight>


=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;


/// <summary>
/// <summary>
Line 1,232: Line 1,232:
}
}
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>¬True = False
<pre>¬True = False
Line 1,276: Line 1,276:
=={{header|C++}}==
=={{header|C++}}==
Essentially the same logic as the [[#Using functions|Using functions]] implementation above, but using class-based encapsulation and overridden operators.
Essentially the same logic as the [[#Using functions|Using functions]] implementation above, but using class-based encapsulation and overridden operators.
<lang cpp>#include <iostream>
<syntaxhighlight lang="cpp">#include <iostream>
#include <stdlib.h>
#include <stdlib.h>


Line 1,349: Line 1,349:
show_op(==);
show_op(==);
return EXIT_SUCCESS;
return EXIT_SUCCESS;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>! ----
<pre>! ----
Line 1,381: Line 1,381:


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
<lang lisp>(defun tri-not (x) (- 1 x))
<syntaxhighlight lang="lisp">(defun tri-not (x) (- 1 x))
(defun tri-and (&rest x) (apply #'* x))
(defun tri-and (&rest x) (apply #'* x))
(defun tri-or (&rest x) (tri-not (apply #'* (mapcar #'tri-not x))))
(defun tri-or (&rest x) (tri-not (apply #'* (mapcar #'tri-not x))))
Line 1,411: Line 1,411:
(print-table #'tri-or "OR")
(print-table #'tri-or "OR")
(print-table #'tri-imply "IMPLY")
(print-table #'tri-imply "IMPLY")
(print-table #'tri-eq "EQUAL")</lang>
(print-table #'tri-eq "EQUAL")</syntaxhighlight>
{{out}}
{{out}}
<pre>NOT:
<pre>NOT:
Line 1,448: Line 1,448:
=={{header|D}}==
=={{header|D}}==
Partial translation of a C entry:
Partial translation of a C entry:
<lang d>import std.stdio;
<syntaxhighlight lang="d">import std.stdio;


struct Trit {
struct Trit {
Line 1,515: Line 1,515:
showOperation!"=="("Equiv");
showOperation!"=="("Equiv");
showOperation!"==>"("Imply");
showOperation!"==>"("Imply");
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>[Not]
<pre>[Not]
Line 1,558: Line 1,558:


=={{header|Delphi}}==
=={{header|Delphi}}==
<lang delphi>unit TrinaryLogic;
<syntaxhighlight lang="delphi">unit TrinaryLogic;


interface
interface
Line 1,613: Line 1,613:
end;
end;


end.</lang>
end.</syntaxhighlight>


And that's the reason why you never on no account ''ever'' should compare against the values of True or False unless you intent ternary logic!
And that's the reason why you never on no account ''ever'' should compare against the values of True or False unless you intent ternary logic!


An alternative version would be using an enum type
An alternative version would be using an enum type
<lang delphi>type TriBool = (tbFalse, tbMaybe, tbTrue);</lang>
<syntaxhighlight lang="delphi">type TriBool = (tbFalse, tbMaybe, tbTrue);</syntaxhighlight>
and defining a set of constants implementing the above tables:
and defining a set of constants implementing the above tables:
<lang delphi>const
<syntaxhighlight lang="delphi">const
tvl_not: array[TriBool] = (tbTrue, tbMaybe, tbFalse);
tvl_not: array[TriBool] = (tbTrue, tbMaybe, tbFalse);
tvl_and: array[TriBool, TriBool] = (
tvl_and: array[TriBool, TriBool] = (
Line 1,642: Line 1,642:
(tbFalse, tbMaybe, tbTrue),
(tbFalse, tbMaybe, tbTrue),
);
);
</syntaxhighlight>
</lang>


That's no real fun, but lookup can then be done with
That's no real fun, but lookup can then be done with
<lang delphi>Result := tvl_and[A, B];</lang>
<syntaxhighlight lang="delphi">Result := tvl_and[A, B];</syntaxhighlight>


=={{header|Elena}}==
=={{header|Elena}}==
ELENA 5.0 :
ELENA 5.0 :
<lang elena>import extensions;
<syntaxhighlight lang="elena">import extensions;
import system'routines;
import system'routines;
import system'collections;
import system'collections;
Line 1,717: Line 1,717:
}
}
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 1,762: Line 1,762:


=={{header|Erlang}}==
=={{header|Erlang}}==
<lang erlang>% Implemented by Arjun Sunel
<syntaxhighlight lang="erlang">% Implemented by Arjun Sunel
-module(ternary).
-module(ternary).
-export([main/0, nott/1, andd/2,orr/2, then/2, equiv/2]).
-export([main/0, nott/1, andd/2,orr/2, then/2, equiv/2]).
Line 1,836: Line 1,836:
io: format("~s\n", [B])
io: format("~s\n", [B])
end.
end.
</syntaxhighlight>
</lang>


=={{header|Factor}}==
=={{header|Factor}}==
For boolean logic, Factor uses ''t'' and ''f'' with the words ''>boolean'', ''not'', ''and'', ''or'', ''xor''. For ternary logic, we add ''m'' and define the words ''>trit'', ''tnot'', ''tand'', ''tor'', ''txor'' and ''t=''. Our new class, ''trit'', is the union class of ''t'', ''m'' and ''f''.
For boolean logic, Factor uses ''t'' and ''f'' with the words ''>boolean'', ''not'', ''and'', ''or'', ''xor''. For ternary logic, we add ''m'' and define the words ''>trit'', ''tnot'', ''tand'', ''tor'', ''txor'' and ''t=''. Our new class, ''trit'', is the union class of ''t'', ''m'' and ''f''.


<lang factor>! rosettacode/ternary/ternary.factor
<syntaxhighlight lang="factor">! rosettacode/ternary/ternary.factor
! http://rosettacode.org/wiki/Ternary_logic
! http://rosettacode.org/wiki/Ternary_logic
USING: combinators kernel ;
USING: combinators kernel ;
Line 1,881: Line 1,881:
{ m [ >trit drop m ] }
{ m [ >trit drop m ] }
{ f [ tnot ] }
{ f [ tnot ] }
} case ;</lang>
} case ;</syntaxhighlight>


Example use:
Example use:
<lang factor>( scratchpad ) CONSTANT: trits { t m f }
<syntaxhighlight lang="factor">( scratchpad ) CONSTANT: trits { t m f }
( scratchpad ) trits [ tnot ] map .
( scratchpad ) trits [ tnot ] map .
{ f m t }
{ f m t }
Line 1,894: Line 1,894:
{ { f m t } { m m m } { t m f } }
{ { f m t } { m m m } { t m f } }
( scratchpad ) trits [ trits swap [ t= ] curry map ] map .
( scratchpad ) trits [ trits swap [ t= ] curry map ] map .
{ { t m f } { m m m } { f m t } }</lang>
{ { t m f } { m m m } { f m t } }</syntaxhighlight>




Line 1,902: Line 1,902:
Standard Forth defines flags 'false' as 0 and 'true' as -1 (all bits set). We thus define 'maybe' as 1 to keep standard binary logic as-is and seamlessly include ternary logic. We may have use truthtables but here functions are more fluid.
Standard Forth defines flags 'false' as 0 and 'true' as -1 (all bits set). We thus define 'maybe' as 1 to keep standard binary logic as-is and seamlessly include ternary logic. We may have use truthtables but here functions are more fluid.


<lang forth>1 constant maybe
<syntaxhighlight lang="forth">1 constant maybe


: tnot dup maybe <> if invert then ;
: tnot dup maybe <> if invert then ;
Line 1,935: Line 1,935:
CR ." [IMPLY]" ' timply table2. CR
CR ." [IMPLY]" ' timply table2. CR
CR ." [EQUIV]" ' tequiv table2. CR
CR ." [EQUIV]" ' tequiv table2. CR
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 1,995: Line 1,995:


Please find the demonstration and compilation with gfortran at the start of the code. A module contains the ternary logic for easy reuse. Consider input redirection from unixdict.txt as vestigial. Or I could delete it.
Please find the demonstration and compilation with gfortran at the start of the code. A module contains the ternary logic for easy reuse. Consider input redirection from unixdict.txt as vestigial. Or I could delete it.
<syntaxhighlight lang="fortran">
<lang FORTRAN>
!-*- mode: compilation; default-directory: "/tmp/" -*-
!-*- mode: compilation; default-directory: "/tmp/" -*-
!Compilation started at Mon May 20 23:05:46
!Compilation started at Mon May 20 23:05:46
Line 2,093: Line 2,093:


end program ternaryLogic
end program ternaryLogic
</syntaxhighlight>
</lang>


=={{header|Free Pascal}}==
=={{header|Free Pascal}}==
Line 2,099: Line 2,099:
Note equivalence and implication are used as proof, they are solved using the basic set instead of a lookup.
Note equivalence and implication are used as proof, they are solved using the basic set instead of a lookup.
Note Since we use a balanced range -1,0,1 multiplication equals EQU
Note Since we use a balanced range -1,0,1 multiplication equals EQU
<lang pascal>{$mode objfpc}
<syntaxhighlight lang="pascal">{$mode objfpc}
unit ternarylogic;
unit ternarylogic;


Line 2,165: Line 2,165:
end;
end;
end.
end.
</syntaxhighlight>
</lang>
<lang pascal>program ternarytests;
<syntaxhighlight lang="pascal">program ternarytests;
{$mode objfpc}
{$mode objfpc}
uses
uses
Line 2,211: Line 2,211:
writeln('F|',tFalse >< tTrue:7, tFalse >< tMaybe:7,tFalse >< tFalse:7);
writeln('F|',tFalse >< tTrue:7, tFalse >< tMaybe:7,tFalse >< tFalse:7);
writeln;
writeln;
end.</lang>
end.</syntaxhighlight>
<pre>
<pre>
Output:
Output:
Line 2,251: Line 2,251:


=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
<lang freebasic>enum trit
<syntaxhighlight lang="freebasic">enum trit
F=-1, M=0, T=1
F=-1, M=0, T=1
end enum
end enum
Line 2,295: Line 2,295:
outstr += " " + symbol(not(i))
outstr += " " + symbol(not(i))
print outstr
print outstr
next i</lang>
next i</syntaxhighlight>
<pre>
<pre>
(AND) ( OR) (EQV) (IMP) (NOT)
(AND) ( OR) (EQV) (IMP) (NOT)
Line 2,321: Line 2,321:
=={{header|Go}}==
=={{header|Go}}==
Go has four operators for the bool type: ==, &&, ||, and !.
Go has four operators for the bool type: ==, &&, ||, and !.
<lang go>package main
<syntaxhighlight lang="go">package main


import "fmt"
import "fmt"
Line 2,395: Line 2,395:
}
}
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,439: Line 2,439:
=={{header|Groovy}}==
=={{header|Groovy}}==
Solution:
Solution:
<lang groovy>enum Trit {
<syntaxhighlight lang="groovy">enum Trit {
TRUE, MAYBE, FALSE
TRUE, MAYBE, FALSE
Line 2,456: Line 2,456:
Trit imply(Trit that) { this.nand(that.not()) }
Trit imply(Trit that) { this.nand(that.not()) }
Trit equiv(Trit that) { this.and(that).or(this.nor(that)) }
Trit equiv(Trit that) { this.and(that).or(this.nor(that)) }
}</lang>
}</syntaxhighlight>


Test:
Test:
<lang groovy>printf 'AND\n '
<syntaxhighlight lang="groovy">printf 'AND\n '
Trit.values().each { b -> printf ('%6s', b) }
Trit.values().each { b -> printf ('%6s', b) }
println '\n ----- ----- -----'
println '\n ----- ----- -----'
Line 2,498: Line 2,498:
Trit.values().each { b -> printf ('%6s', a.equiv(b)) }
Trit.values().each { b -> printf ('%6s', a.equiv(b)) }
println()
println()
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 2,538: Line 2,538:
All operations given in terms of NAND, the functionally-complete operation.
All operations given in terms of NAND, the functionally-complete operation.


<lang Haskell>import Prelude hiding (Bool(..), not, (&&), (||), (==))
<syntaxhighlight lang="haskell">import Prelude hiding (Bool(..), not, (&&), (||), (==))


main = mapM_ (putStrLn . unlines . map unwords)
main = mapM_ (putStrLn . unlines . map unwords)
Line 2,574: Line 2,574:
where header = map (:[]) (take ((length $ head xs) - 1) ['A'..]) ++ [name]
where header = map (:[]) (take ((length $ head xs) - 1) ['A'..]) ++ [name]


pad s = s ++ replicate (5 - length s) ' '</lang>
pad s = s ++ replicate (5 - length s) ' '</syntaxhighlight>


{{out}}
{{out}}
Line 2,634: Line 2,634:




<lang Icon>$define TRUE 1
<syntaxhighlight lang="icon">$define TRUE 1
$define FALSE -1
$define FALSE -1
$define UNKNOWN 0
$define UNKNOWN 0
Line 2,695: Line 2,695:
procedure xor3(a,b) #: xor of two trits or error if invalid
procedure xor3(a,b) #: xor of two trits or error if invalid
return not3(eq3(a,b))
return not3(eq3(a,b))
end</lang>
end</syntaxhighlight>


{{libheader|Icon Programming Library}}
{{libheader|Icon Programming Library}}
Line 2,746: Line 2,746:
maybe: 0.5
maybe: 0.5


<lang j>not=: -.
<syntaxhighlight lang="j">not=: -.
and=: <.
and=: <.
or =: >.
or =: >.
if =: (>. -.)"0~
if =: (>. -.)"0~
eq =: (<.&-. >. <.)"0</lang>
eq =: (<.&-. >. <.)"0</syntaxhighlight>


Example use:
Example use:


<lang j> not 0 0.5 1
<syntaxhighlight lang="j"> not 0 0.5 1
1 0.5 0
1 0.5 0


Line 2,775: Line 2,775:
1 0.5 0
1 0.5 0
0.5 0.5 0.5
0.5 0.5 0.5
0 0.5 1</lang>
0 0.5 1</syntaxhighlight>


Note that this implementation is a special case of "[[wp:fuzzy logic|fuzzy logic]]" (using a limited set of values).
Note that this implementation is a special case of "[[wp:fuzzy logic|fuzzy logic]]" (using a limited set of values).
Line 2,783: Line 2,783:
Note that we might instead define values between 0 and 1 to represent independent probabilities:
Note that we might instead define values between 0 and 1 to represent independent probabilities:


<lang J>not=: -.
<syntaxhighlight lang="j">not=: -.
and=: *
and=: *
or=: *&.-.
or=: *&.-.
if =: (or -.)"0~
if =: (or -.)"0~
eq =: (*&-. or *)"0</lang>
eq =: (*&-. or *)"0</syntaxhighlight>


However, while this might be a more intellectually satisfying approach, this gives us some different results from the task requirement, for the combination of two "maybe" values (we could "fix" this by adding some "logic" which replaced any non-integer value with "0.5" - this would satisfy literal compliance with the task specification and might even be a valid engineering choice if we are implementing in hardware, for example):
However, while this might be a more intellectually satisfying approach, this gives us some different results from the task requirement, for the combination of two "maybe" values (we could "fix" this by adding some "logic" which replaced any non-integer value with "0.5" - this would satisfy literal compliance with the task specification and might even be a valid engineering choice if we are implementing in hardware, for example):


<lang J> not 0 0.5 1
<syntaxhighlight lang="j"> not 0 0.5 1
1 0.5 0
1 0.5 0


Line 2,812: Line 2,812:
1 0.5 0
1 0.5 0
0.5 0.4375 0.5
0.5 0.4375 0.5
0 0.5 1</lang>
0 0.5 1</syntaxhighlight>


Another interesting possibility would involve using George Boole's original operations. This leaves us without any "not", (if we include the definition of logical negation which was later added to the definition of Boolean algebra, then the only numbers which can be used with Boolean algebra are 1 and 0). So, it's not clear how we would implement "if" or "eq". However, "and" and "or" would look like this:
Another interesting possibility would involve using George Boole's original operations. This leaves us without any "not", (if we include the definition of logical negation which was later added to the definition of Boolean algebra, then the only numbers which can be used with Boolean algebra are 1 and 0). So, it's not clear how we would implement "if" or "eq". However, "and" and "or" would look like this:


<lang J>and=: *.
<syntaxhighlight lang="j">and=: *.
or=: +.</lang>
or=: +.</syntaxhighlight>


And, the boolean result tables would look like this:
And, the boolean result tables would look like this:


<lang J> 0 0.5 1 and/ 0 0.5 1
<syntaxhighlight lang="j"> 0 0.5 1 and/ 0 0.5 1
0 0 0
0 0 0
0 0.5 1
0 0.5 1
Line 2,829: Line 2,829:
0 0.5 1
0 0.5 1
0.5 0.5 0.5
0.5 0.5 0.5
1 0.5 1</lang>
1 0.5 1</syntaxhighlight>


=={{header|Java}}==
=={{header|Java}}==
{{works with|Java|1.5+}}
{{works with|Java|1.5+}}
<lang java5>public class Logic{
<syntaxhighlight lang="java5">public class Logic{
public static enum Trit{
public static enum Trit{
TRUE, MAYBE, FALSE;
TRUE, MAYBE, FALSE;
Line 2,900: Line 2,900:
}
}
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>not TRUE: FALSE
<pre>not TRUE: FALSE
Line 2,918: Line 2,918:
Let's use the trit already available in JavaScript:
Let's use the trit already available in JavaScript:
true, false (both boolean) and undefined…
true, false (both boolean) and undefined…
<lang JavaScript>var L3 = new Object();
<syntaxhighlight lang="javascript">var L3 = new Object();


L3.not = function(a) {
L3.not = function(a) {
Line 2,951: Line 2,951:
return L3.and(L3.ifThen(a, b), L3.ifThen(b, a));
return L3.and(L3.ifThen(a, b), L3.ifThen(b, a));
}
}
</syntaxhighlight>
</lang>
… and try these:
… and try these:
<lang>
<syntaxhighlight lang="text">
L3.not(true) // false
L3.not(true) // false
L3.not(var a) // undefined
L3.not(var a) // undefined
Line 2,964: Line 2,964:


L3.iff(a, 2 == 2) // undefined
L3.iff(a, 2 == 2) // undefined
</syntaxhighlight>
</lang>
Here is a compact solution
Here is a compact solution
<syntaxhighlight lang="javascript">
<lang Javascript>
trit = {false: 'F', maybe: 'U', true: 'T'}
trit = {false: 'F', maybe: 'U', true: 'T'}
nand = (a, b) => (a == trit.false || b == trit.false) ? trit.true : (a == trit.maybe || b == trit.maybe) ? trit.maybe : trit.false
nand = (a, b) => (a == trit.false || b == trit.false) ? trit.true : (a == trit.maybe || b == trit.maybe) ? trit.maybe : trit.false
Line 2,976: Line 2,976:
iff = (a, b) => or(and(a, b), nor(a, b))
iff = (a, b) => or(and(a, b), nor(a, b))
xor = (a, b) => not(iff(a, b))
xor = (a, b) => not(iff(a, b))
</syntaxhighlight>
</lang>
... to test it
... to test it
<syntaxhighlight lang="javascript">
<lang Javascript>
functor = {nand, and, or, nor, implies, iff, xor}
functor = {nand, and, or, nor, implies, iff, xor}
display = {nand: '⊼', and: '∧', or: '∨', nor: '⊽', implies: '⇒', iff: '⇔', xor: '⊻', not: '¬'}
display = {nand: '⊼', and: '∧', or: '∨', nor: '⊽', implies: '⇒', iff: '⇔', xor: '⊻', not: '¬'}
Line 2,994: Line 2,994:
}
}
console.log(log)
console.log(log)
</syntaxhighlight>
</lang>
...Output:
...Output:
<lang>
<syntaxhighlight lang="text">
NOT
NOT
¬F = F
¬F = F
Line 3,012: Line 3,012:
T ⊼ U = U T ∧ U = U T ∨ U = T T ⊽ U = F T ⇒ U = U T ⇔ U = U T ⊻ U = U
T ⊼ U = U T ∧ U = U T ∨ U = T T ⊽ U = F T ⇒ U = U T ⇔ U = U T ⊻ U = U
T ⊼ T = F T ∧ T = T T ∨ T = T T ⊽ T = F T ⇒ T = T T ⇔ T = T T ⊻ T = F
T ⊼ T = F T ∧ T = T T ∨ T = T T ⊽ T = F T ⇒ T = T T ⇔ T = T T ⊻ T = F
</syntaxhighlight>
</lang>


=={{header|jq}}==
=={{header|jq}}==
Line 3,018: Line 3,018:
as the three values since ternary logic agrees with Boolean logic for true and false, and because jq prints these three values consistently.
as the three values since ternary logic agrees with Boolean logic for true and false, and because jq prints these three values consistently.


For consistency, all the ternary logic operators are defined here with the prefix "ternary_", but such a prefix is only needed for "not", "and", and "or", as these are jq keywords. <lang jq>def ternary_nand(a; b):
For consistency, all the ternary logic operators are defined here with the prefix "ternary_", but such a prefix is only needed for "not", "and", and "or", as these are jq keywords. <syntaxhighlight lang="jq">def ternary_nand(a; b):
if a == false or b == false then true
if a == false or b == false then true
elif a == "maybe" or b == "maybe" then "maybe"
elif a == "maybe" or b == "maybe" then "maybe"
Line 3,050: Line 3,050:
display_equiv( (false, "maybe", true ); (false, "maybe", true) ),
display_equiv( (false, "maybe", true ); (false, "maybe", true) ),
"etc etc"
"etc etc"
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>"false and false is false"
<pre>"false and false is false"
Line 3,076: Line 3,076:
{{works with|Julia|0.6}}
{{works with|Julia|0.6}}


<lang julia>@enum Trit False Maybe True
<syntaxhighlight lang="julia">@enum Trit False Maybe True
const trits = (False, Maybe, True)
const trits = (False, Maybe, True)


Line 3,102: Line 3,102:
for a in trits
for a in trits
println(join(@sprintf("%10s ≡ %5s is %5s", a, b, a ≡ b) for b in trits))
println(join(@sprintf("%10s ≡ %5s is %5s", a, b, a ≡ b) for b in trits))
end</lang>
end</syntaxhighlight>


{{out}}
{{out}}
Line 3,129: Line 3,129:


With Julia 1.0 and the new type <tt>missing</tt>, three-value logic is implemented by default
With Julia 1.0 and the new type <tt>missing</tt>, three-value logic is implemented by default
<lang julia># built-in: true, false and missing
<syntaxhighlight lang="julia"># built-in: true, false and missing


using Printf
using Printf
Line 3,160: Line 3,160:
for (A, B) in Iterators.product(tril, tril)
for (A, B) in Iterators.product(tril, tril)
@printf("%8s | %8s | %8s\n", A, B, A ⊃ B)
@printf("%8s | %8s | %8s\n", A, B, A ⊃ B)
end</lang>
end</syntaxhighlight>


{{out}}
{{out}}
Line 3,212: Line 3,212:


=={{header|Kotlin}}==
=={{header|Kotlin}}==
<lang scala>// version 1.1.2
<syntaxhighlight lang="scala">// version 1.1.2


enum class Trit {
enum class Trit {
Line 3,297: Line 3,297:
println()
println()
}
}
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 3,336: Line 3,336:
{{works with|langur|0.6.12}}
{{works with|langur|0.6.12}}


<lang langur># borrowing null for "maybe"
<syntaxhighlight lang="langur"># borrowing null for "maybe"
val .trSet = [false, null, true]
val .trSet = [false, null, true]


Line 3,391: Line 3,391:
writeln $"\.a:.F; \.b:.F; \.a ==? .b:.F;"
writeln $"\.a:.F; \.b:.F; \.a ==? .b:.F;"
}
}
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 3,444: Line 3,444:


=={{header|Liberty BASIC}}==
=={{header|Liberty BASIC}}==
<syntaxhighlight lang="lb">
<lang lb>
'ternary logic
'ternary logic
'0 1 2
'0 1 2
Line 3,515: Line 3,515:
longName3$ = word$("False,Don't know,True", i+1, ",")
longName3$ = word$("False,Don't know,True", i+1, ",")
end function
end function
</lang>
</syntaxhighlight>


{{out}}
{{out}}
Line 3,548: Line 3,548:
The following script generates all truth tables for Maple logical operations. Note that in addition to the usual built-in logical operators for '''not''', '''or''', '''and''', and '''xor''', Maple also has '''implies'''.
The following script generates all truth tables for Maple logical operations. Note that in addition to the usual built-in logical operators for '''not''', '''or''', '''and''', and '''xor''', Maple also has '''implies'''.


<lang Maple>tv := [true, false, FAIL];
<syntaxhighlight lang="maple">tv := [true, false, FAIL];
NotTable := Array(1..3, i->not tv[i] );
NotTable := Array(1..3, i->not tv[i] );
AndTable := Array(1..3, 1..3, (i,j)->tv[i] and tv[j] );
AndTable := Array(1..3, 1..3, (i,j)->tv[i] and tv[j] );
OrTable := Array(1..3, 1..3, (i,j)->tv[i] or tv[j] );
OrTable := Array(1..3, 1..3, (i,j)->tv[i] or tv[j] );
XorTable := Array(1..3, 1..3, (i,j)->tv[i] xor tv[j] );
XorTable := Array(1..3, 1..3, (i,j)->tv[i] xor tv[j] );
ImpliesTable := Array(1..3, 1..3, (i,j)->tv[i] implies tv[j] );</lang>
ImpliesTable := Array(1..3, 1..3, (i,j)->tv[i] implies tv[j] );</syntaxhighlight>


{{Out}}
{{Out}}


<lang Maple>> tv := [true, false, FAIL];
<syntaxhighlight lang="maple">> tv := [true, false, FAIL];
tv := [true, false, FAIL]
tv := [true, false, FAIL]


Line 3,589: Line 3,589:
ImpliesTable := [true true true]
ImpliesTable := [true true true]
[ ]
[ ]
[true FAIL FAIL]</lang>
[true FAIL FAIL]</syntaxhighlight>


=={{header|Mathematica}}/{{header|Wolfram Language}}==
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Type definition is not allowed in Mathematica. We can just use the build-in symbols "True" and "False", and add a new symbol "Maybe".
Type definition is not allowed in Mathematica. We can just use the build-in symbols "True" and "False", and add a new symbol "Maybe".
<lang mathematica>Maybe /: ! Maybe = Maybe;
<syntaxhighlight lang="mathematica">Maybe /: ! Maybe = Maybe;
Maybe /: (And | Or | Nand | Nor | Xor | Xnor | Implies | Equivalent)[Maybe, Maybe] = Maybe;</lang>
Maybe /: (And | Or | Nand | Nor | Xor | Xnor | Implies | Equivalent)[Maybe, Maybe] = Maybe;</syntaxhighlight>
Example:
Example:
<lang mathematica>trits = {True, Maybe, False};
<syntaxhighlight lang="mathematica">trits = {True, Maybe, False};
Print@Grid[
Print@Grid[
ArrayFlatten[{{{{Not}}, {{Null}}}, {List /@ trits,
ArrayFlatten[{{{{Not}}, {{Null}}}, {List /@ trits,
Line 3,604: Line 3,604:
Null}}}, {{{Null}}, {trits}}, {List /@ trits,
Null}}}, {{{Null}}, {trits}}, {List /@ trits,
Outer[operator, trits, trits]}}]], {operator, {And, Or, Nand,
Outer[operator, trits, trits]}}]], {operator, {And, Or, Nand,
Nor, Xor, Xnor, Implies, Equivalent}}]</lang>
Nor, Xor, Xnor, Implies, Equivalent}}]</syntaxhighlight>
{{out}}
{{out}}
<pre>Not
<pre>Not
Line 3,668: Line 3,668:


=={{header|МК-61/52}}==
=={{header|МК-61/52}}==
<lang>П0 Сx С/П ^ 1 + 3 * + 1
<syntaxhighlight lang="text">П0 Сx С/П ^ 1 + 3 * + 1
+ 3 x^y ИП0 <-> / [x] ^ ^ 3
+ 3 x^y ИП0 <-> / [x] ^ ^ 3
/ [x] 3 * - 1 - С/П 1 5
/ [x] 3 * - 1 - С/П 1 5
6 3 3 БП 00 1 9 5 6 9
6 3 3 БП 00 1 9 5 6 9
БП 00 1 5 9 2 9 БП 00 1
БП 00 1 5 9 2 9 БП 00 1
5 6 6 5 БП 00 /-/ ЗН С/П</lang>
5 6 6 5 БП 00 /-/ ЗН С/П</syntaxhighlight>


<u>Instruction</u>:
<u>Instruction</u>:
Line 3,684: Line 3,684:


=={{header|Nim}}==
=={{header|Nim}}==
<lang nim>type Trit* = enum ttrue, tmaybe, tfalse
<syntaxhighlight lang="nim">type Trit* = enum ttrue, tmaybe, tfalse


proc `$`*(a: Trit): string =
proc `$`*(a: Trit): string =
Line 3,739: Line 3,739:
echo "$# or $#: $#".format(op1, op2, op1 or op2)
echo "$# or $#: $#".format(op1, op2, op1 or op2)
echo "$# then $#: $#".format(op1, op2, op1.then op2)
echo "$# then $#: $#".format(op1, op2, op1.then op2)
echo "$# equiv $#: $#".format(op1, op2, op1.equiv op2)</lang>
echo "$# equiv $#: $#".format(op1, op2, op1.equiv op2)</syntaxhighlight>
{{out}}
{{out}}
<pre>Not T: F
<pre>Not T: F
Line 3,783: Line 3,783:
=={{header|OCaml}}==
=={{header|OCaml}}==


<lang ocaml>type trit = True | False | Maybe
<syntaxhighlight lang="ocaml">type trit = True | False | Maybe


let t_not = function
let t_not = function
Line 3,826: Line 3,826:
print t_imply "Then";
print t_imply "Then";
print t_eq "Equiv";
print t_eq "Equiv";
;;</lang>
;;</syntaxhighlight>


{{out}}
{{out}}
Line 3,876: Line 3,876:
=== Using a general binary -> ternary transform ===
=== Using a general binary -> ternary transform ===
Instead of writing all of the truth-tables by hand, we can construct a general binary -> ternary transform and apply it to any logical function we want:
Instead of writing all of the truth-tables by hand, we can construct a general binary -> ternary transform and apply it to any logical function we want:
<lang OCaml>type trit = True | False | Maybe
<syntaxhighlight lang="ocaml">type trit = True | False | Maybe


let to_bin = function True -> [true] | False -> [false] | Maybe -> [true;false]
let to_bin = function True -> [true] | False -> [false] | Maybe -> [true;false]
Line 3,915: Line 3,915:
table2 "or" t_or;;
table2 "or" t_or;;
table2 "equiv" t_equiv;;
table2 "equiv" t_equiv;;
table2 "implies" t_imply;;</lang>
table2 "implies" t_imply;;</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 3,968: Line 3,968:


=={{header|ooRexx}}==
=={{header|ooRexx}}==
<syntaxhighlight lang="oorexx">
<lang ooRexx>
tritValues = .array~of(.trit~true, .trit~false, .trit~maybe)
tritValues = .array~of(.trit~true, .trit~false, .trit~maybe)
tab = '09'x
tab = '09'x
Line 4,093: Line 4,093:
else if self == .trit~maybe then return .trit~maybe
else if self == .trit~maybe then return .trit~maybe
else return \other
else return \other
</syntaxhighlight>
</lang>


<pre>
<pre>
Line 4,147: Line 4,147:


=={{header|Pascal}}==
=={{header|Pascal}}==
<lang pascal>Program TernaryLogic (output);
<syntaxhighlight lang="pascal">Program TernaryLogic (output);


type
type
Line 4,237: Line 4,237:
writeln('False ', terToStr(terEquals(terTrue,terFalse)), ' ', terToStr(terEquals(terMayBe,terFalse)), ' ', terToStr(terEquals(terFalse,terFalse)));
writeln('False ', terToStr(terEquals(terTrue,terFalse)), ' ', terToStr(terEquals(terMayBe,terFalse)), ' ', terToStr(terEquals(terFalse,terFalse)));
writeln;
writeln;
end.</lang>
end.</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 4,270: Line 4,270:
=={{header|Perl}}==
=={{header|Perl}}==
File <TT>Trit.pm</TT>:
File <TT>Trit.pm</TT>:
<lang perl>package Trit;
<syntaxhighlight lang="perl">package Trit;


# -1 = false ; 0 = maybe ; 1 = true
# -1 = false ; 0 = maybe ; 1 = true
Line 4,339: Line 4,339:
sub or { new Trit(max(${$_[0]}, ${$_[1]}) ) }
sub or { new Trit(max(${$_[0]}, ${$_[1]}) ) }


sub equiv { new Trit( ${$_[0]} * ${$_[1]} ) }</lang>
sub equiv { new Trit( ${$_[0]} * ${$_[1]} ) }</syntaxhighlight>
File <TT>test.pl</TT>:
File <TT>test.pl</TT>:
<lang perl>use Trit ':all';
<syntaxhighlight lang="perl">use Trit ':all';


my @a = (TRUE(), MAYBE(), FALSE());
my @a = (TRUE(), MAYBE(), FALSE());
Line 4,383: Line 4,383:
}
}
print "\n";
print "\n";
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>a NOT a
<pre>a NOT a
Line 4,412: Line 4,412:
=={{header|Phix}}==
=={{header|Phix}}==
{{libheader|Phix/basics}}
{{libheader|Phix/basics}}
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">enum</span> <span style="color: #000000;">T</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">M</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">F</span>
<span style="color: #008080;">enum</span> <span style="color: #000000;">T</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">M</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">F</span>
<span style="color: #008080;">type</span> <span style="color: #000000;">ternary</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">T</span><span style="color: #0000FF;">,</span><span style="color: #000000;">M</span><span style="color: #0000FF;">,</span><span style="color: #000000;">F</span><span style="color: #0000FF;">})</span> <span style="color: #008080;">end</span> <span style="color: #008080;">type</span>
<span style="color: #008080;">type</span> <span style="color: #000000;">ternary</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">T</span><span style="color: #0000FF;">,</span><span style="color: #000000;">M</span><span style="color: #0000FF;">,</span><span style="color: #000000;">F</span><span style="color: #0000FF;">})</span> <span style="color: #008080;">end</span> <span style="color: #008080;">type</span>
Line 4,467: Line 4,467:
<span style="color: #000000;">show_truth_table</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t_implies</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"imp"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">show_truth_table</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t_implies</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"imp"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">show_truth_table</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t_equal</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"eq"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">show_truth_table</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t_equal</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"eq"</span><span style="color: #0000FF;">)</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 4,509: Line 4,509:
=={{header|PHP}}==
=={{header|PHP}}==
Save the sample code as executable shell script on your *nix system:
Save the sample code as executable shell script on your *nix system:
<lang PHP>#!/usr/bin/php
<syntaxhighlight lang="php">#!/usr/bin/php
<?php
<?php


Line 4,571: Line 4,571:
}
}


</syntaxhighlight>
</lang>
Sample output:
Sample output:
<pre>--- Sample output for a equivalent b ---
<pre>--- Sample output for a equivalent b ---
Line 4,587: Line 4,587:


=={{header|Picat}}==
=={{header|Picat}}==
<lang Picat>main =>
<syntaxhighlight lang="picat">main =>
(show_op1('!') ; true),
(show_op1('!') ; true),
nl,
nl,
Line 4,644: Line 4,644:
nl
nl
end,
end,
nl.</lang>
nl.</syntaxhighlight>


{{out}}
{{out}}
Line 4,679: Line 4,679:


===Simple examples===
===Simple examples===
<lang Picat>main =>
<syntaxhighlight lang="picat">main =>
println(ternary(10 > 3,'->',maybe).ternary('!')),
println(ternary(10 > 3,'->',maybe).ternary('!')),
println(ternary(4 < 18,'/\\',$not membchk('a',"picat")).ternary('->',maybe).ternary('==',true)).</lang>
println(ternary(4 < 18,'/\\',$not membchk('a',"picat")).ternary('->',maybe).ternary('==',true)).</syntaxhighlight>


{{out}}
{{out}}
Line 4,689: Line 4,689:
=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
In addition for the standard T (for "true") and NIL (for "false") we define 0 (zero, for "maybe").
In addition for the standard T (for "true") and NIL (for "false") we define 0 (zero, for "maybe").
<lang PicoLisp>(de 3not (A)
<syntaxhighlight lang="picolisp">(de 3not (A)
(or (=0 A) (not A)) )
(or (=0 A) (not A)) )


Line 4,713: Line 4,713:
((=T A) B)
((=T A) B)
((=0 A) 0)
((=0 A) 0)
(T (3not B)) ) )</lang>
(T (3not B)) ) )</syntaxhighlight>
Test:
Test:
<lang PicoLisp>(for X '(T 0 NIL)
<syntaxhighlight lang="picolisp">(for X '(T 0 NIL)
(println 'not X '-> (3not X)) )
(println 'not X '-> (3not X)) )


Line 4,721: Line 4,721:
(for X '(T 0 NIL)
(for X '(T 0 NIL)
(for Y '(T 0 NIL)
(for Y '(T 0 NIL)
(println X (car Fun) Y '-> ((cdr Fun) X Y)) ) ) )</lang>
(println X (car Fun) Y '-> ((cdr Fun) X Y)) ) ) )</syntaxhighlight>
{{out}}
{{out}}
<pre>not T -> NIL
<pre>not T -> NIL
Line 4,765: Line 4,765:
=={{header|PureBasic}}==
=={{header|PureBasic}}==
{{trans|FreeBasic}}
{{trans|FreeBasic}}
<lang PureBasic>DataSection
<syntaxhighlight lang="purebasic">DataSection
TLogic:
TLogic:
Data.i -1,0,1
Data.i -1,0,1
Line 4,822: Line 4,822:
Next
Next
EndIf
EndIf
Input()</lang>
Input()</syntaxhighlight>
{{out}}
{{out}}
<pre> (AND) ( OR) (EQV) (IMP) (NOT)
<pre> (AND) ( OR) (EQV) (IMP) (NOT)
Line 4,834: Line 4,834:
=={{header|Python}}==
=={{header|Python}}==
In Python, the keywords 'and', 'not', and 'or' are coerced to always work as boolean operators. I have therefore overloaded the boolean bitwise operators &, |, ^ to provide the required functionality.
In Python, the keywords 'and', 'not', and 'or' are coerced to always work as boolean operators. I have therefore overloaded the boolean bitwise operators &, |, ^ to provide the required functionality.
<lang python>class Trit(int):
<syntaxhighlight lang="python">class Trit(int):
def __new__(cls, value):
def __new__(cls, value):
if value == 'TRUE':
if value == 'TRUE':
Line 4,962: Line 4,962:
for b in values:
for b in values:
expr = '%s %s %s' % (a, op, b)
expr = '%s %s %s' % (a, op, b)
print(' %s = %s' % (expr, eval(expr)))</lang>
print(' %s = %s' % (expr, eval(expr)))</syntaxhighlight>


{{out}}
{{out}}
Line 5,014: Line 5,014:


=={{header|Quackery}}==
=={{header|Quackery}}==
<syntaxhighlight lang="quackery ">
<lang Quackery >
[ 2 ] is maybe ( --> t )
[ 2 ] is maybe ( --> t )
Line 5,119: Line 5,119:
say " false | " false true t.<=> paddedtrit sp
say " false | " false true t.<=> paddedtrit sp
say "| " false maybe t.<=> paddedtrit sp
say "| " false maybe t.<=> paddedtrit sp
say "| " false false t.<=> paddedtrit cr</lang>
say "| " false false t.<=> paddedtrit cr</syntaxhighlight>


'''Output:'''
'''Output:'''
Line 5,152: Line 5,152:


=={{header|Racket}}==
=={{header|Racket}}==
<lang racket>#lang typed/racket
<syntaxhighlight lang="racket">#lang typed/racket


; to avoid the hassle of adding a maybe value that is as special as
; to avoid the hassle of adding a maybe value that is as special as
Line 5,213: Line 5,213:
(for*: : Void ([a (in-list '(true maybe false))]
(for*: : Void ([a (in-list '(true maybe false))]
[b (in-list '(true maybe false))])
[b (in-list '(true maybe false))])
(printf "~a ~a ~a = ~a~n" a (object-name proc) b (proc a b))))</lang>
(printf "~a ~a ~a = ~a~n" a (object-name proc) b (proc a b))))</syntaxhighlight>


{{out}}
{{out}}
Line 5,263: Line 5,263:
The precedence of each operator is specified as equivalent to an existing operator. We've taken the liberty of using a double arrow for implication, to avoid confusing it with <tt>⊃</tt>, (U+2283 SUPERSET OF).
The precedence of each operator is specified as equivalent to an existing operator. We've taken the liberty of using a double arrow for implication, to avoid confusing it with <tt>⊃</tt>, (U+2283 SUPERSET OF).


<lang perl6># Implementation:
<syntaxhighlight lang="raku" line># Implementation:
enum Trit <Foo Moo Too>;
enum Trit <Foo Moo Too>;


Line 5,309: Line 5,309:
Foo ∧ Too ∨ Foo ⇒ Foo ≡ Too,
Foo ∧ Too ∨ Foo ⇒ Foo ≡ Too,
Foo ∧ Too ∨ Too ⇒ Foo ≡ Foo,
Foo ∧ Too ∨ Too ⇒ Foo ≡ Foo,
);</lang>
);</syntaxhighlight>


{{out}}
{{out}}
Line 5,347: Line 5,347:
{{Works with|Red|0.6.4}}
{{Works with|Red|0.6.4}}


<lang Red>Red ["Ternary logic"]
<syntaxhighlight lang="red">Red ["Ternary logic"]


; define trits as a set of 3 Red words: 'oui, 'non and 'bof
; define trits as a set of 3 Red words: 'oui, 'non and 'bof
Line 5,399: Line 5,399:
print rejoin [pad mold s 25 " " do s]
print rejoin [pad mold s 25 " " do s]
]
]
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 5,416: Line 5,416:
=={{header|REXX}}==
=={{header|REXX}}==
This REXX program is a re-worked version of the REXX program used for the Rosetta Code task: &nbsp; ''truth table''.
This REXX program is a re-worked version of the REXX program used for the Rosetta Code task: &nbsp; ''truth table''.
<lang rexx>/*REXX program displays a ternary truth table [true, false, maybe] for the variables */
<syntaxhighlight lang="rexx">/*REXX program displays a ternary truth table [true, false, maybe] for the variables */
/*──── and one or more expressions. */
/*──── and one or more expressions. */
/*──── Infix notation is supported with one character propositional constants. */
/*──── Infix notation is supported with one character propositional constants. */
Line 5,611: Line 5,611:
otherwise return -13 /*error, unknown function.*/
otherwise return -13 /*error, unknown function.*/
end /*select*/
end /*select*/
</syntaxhighlight>
</lang>
Some older REXXes don't have a &nbsp; '''changestr''' &nbsp; BIF, so one is included here &nbsp; ──► &nbsp; [[CHANGESTR.REX]].
Some older REXXes don't have a &nbsp; '''changestr''' &nbsp; BIF, so one is included here &nbsp; ──► &nbsp; [[CHANGESTR.REX]].
<br><br>
<br><br>
Line 5,695: Line 5,695:


{{works with|Ruby|1.9}}
{{works with|Ruby|1.9}}
<lang ruby># trit.rb - ternary logic
<syntaxhighlight lang="ruby"># trit.rb - ternary logic
# http://rosettacode.org/wiki/Ternary_logic
# http://rosettacode.org/wiki/Ternary_logic


Line 5,779: Line 5,779:
# false.trit == obj # => false, maybe or true
# false.trit == obj # => false, maybe or true
def trit; TritMagic; end
def trit; TritMagic; end
end</lang>
end</syntaxhighlight>


This IRB session shows ternary not, and, or, equal.
This IRB session shows ternary not, and, or, equal.


<lang ruby>$ irb
<syntaxhighlight lang="ruby">$ irb
irb(main):001:0> require './trit'
irb(main):001:0> require './trit'
=> true
=> true
Line 5,799: Line 5,799:
=> false
=> false
irb(main):008:0> false.trit == maybe
irb(main):008:0> false.trit == maybe
=> maybe</lang>
=> maybe</syntaxhighlight>


This program shows all 9 outcomes from <code>a.trit ^ b</code>.
This program shows all 9 outcomes from <code>a.trit ^ b</code>.


<lang ruby>require 'trit'
<syntaxhighlight lang="ruby">require 'trit'
maybe = MAYBE
maybe = MAYBE


Line 5,810: Line 5,810:
printf "%5s ^ %5s => %5s\n", a, b, a.trit ^ b
printf "%5s ^ %5s => %5s\n", a, b, a.trit ^ b
end
end
end</lang>
end</syntaxhighlight>


<pre>$ ruby -I. trit-xor.rb
<pre>$ ruby -I. trit-xor.rb
Line 5,824: Line 5,824:


=={{header|Run BASIC}}==
=={{header|Run BASIC}}==
<lang runbasic>testFalse = 0 ' F
<syntaxhighlight lang="runbasic">testFalse = 0 ' F
testDoNotKnow = 1 ' ?
testDoNotKnow = 1 ' ?
testTrue = 2 ' T
testTrue = 2 ' T
Line 5,881: Line 5,881:
function longName3$(i)
function longName3$(i)
longName3$ = word$("False,Don't know,True", i+1, ",")
longName3$ = word$("False,Don't know,True", i+1, ",")
end function</lang><pre>Short and long names for ternary logic values
end function</syntaxhighlight><pre>Short and long names for ternary logic values
F False
F False
? Don't know
? Don't know
Line 5,897: Line 5,897:
=={{header|Rust}}==
=={{header|Rust}}==
{{trans|Kotlin}}
{{trans|Kotlin}}
<lang Rust>use std::{ops, fmt};
<syntaxhighlight lang="rust">use std::{ops, fmt};


#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug)]
Line 6,003: Line 6,003:
println!();
println!();
}
}
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 6,037: Line 6,037:


=={{header|Scala}}==
=={{header|Scala}}==
<lang scala>sealed trait Trit { self =>
<syntaxhighlight lang="scala">sealed trait Trit { self =>
def nand(that:Trit):Trit=(this,that) match {
def nand(that:Trit):Trit=(this,that) match {
case (TFalse, _) => TTrue
case (TFalse, _) => TTrue
Line 6,069: Line 6,069:
println("\n- Equiv -")
println("\n- Equiv -")
for(a<-v; b<-v) println("%6s : %6s => %6s".format(a, b, a equiv b))
for(a<-v; b<-v) println("%6s : %6s => %6s".format(a, b, a equiv b))
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>- NOT -
<pre>- NOT -
Line 6,139: Line 6,139:
which use also short circuit evaluation.
which use also short circuit evaluation.


<lang seed7>$ include "seed7_05.s7i";
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i";


const type: trit is new enum
const type: trit is new enum
Line 6,252: Line 6,252:
writeTable(operand1 -> operand2, "->");
writeTable(operand1 -> operand2, "->");
writeTable(operand1 == operand2, "==");
writeTable(operand1 == operand2, "==");
end func;</lang>
end func;</syntaxhighlight>


{{out}}
{{out}}
Line 6,293: Line 6,293:
=={{header|Tcl}}==
=={{header|Tcl}}==
The simplest way of doing this is by constructing the operations as truth tables. The code below uses an abbreviated form of truth table.
The simplest way of doing this is by constructing the operations as truth tables. The code below uses an abbreviated form of truth table.
<lang tcl>package require Tcl 8.5
<syntaxhighlight lang="tcl">package require Tcl 8.5
namespace eval ternary {
namespace eval ternary {
# Code generator
# Code generator
Line 6,359: Line 6,359:
* false
* false
}
}
}</lang>
}</syntaxhighlight>
Demonstrating:
Demonstrating:
<lang tcl>namespace import ternary::*
<syntaxhighlight lang="tcl">namespace import ternary::*
puts "x /\\ y == x \\/ y"
puts "x /\\ y == x \\/ y"
puts " x | y || result"
puts " x | y || result"
Line 6,370: Line 6,370:
puts [format " %-5s | %-5s || %-5s" $x $y $z]
puts [format " %-5s | %-5s || %-5s" $x $y $z]
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 6,390: Line 6,390:
=={{header|True BASIC}}==
=={{header|True BASIC}}==
{{trans|BASIC256}}
{{trans|BASIC256}}
<lang basic>
<syntaxhighlight lang="basic">
FUNCTION and3(a, b)
FUNCTION and3(a, b)
IF a < b then LET and3 = a else LET and3 = b
IF a < b then LET and3 = a else LET and3 = b
Line 6,457: Line 6,457:
NEXT a
NEXT a
END
END
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 6,475: Line 6,475:
Below is an example of how this would look, which can be compared to traditional ternary usage:
Below is an example of how this would look, which can be compared to traditional ternary usage:


<lang vlang>import math
<syntaxhighlight lang="vlang">import math


fn main() {
fn main() {
Line 6,537: Line 6,537:
fn ternary_equiv(a f64, b f64) string {
fn ternary_equiv(a f64, b f64) string {
return if a == b {'1.'} else if a == 1 {b.str()} else if b == 1 {a.str()} else {'0.5'}
return if a == b {'1.'} else if a == 1 {b.str()} else if b == 1 {a.str()} else {'0.5'}
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 6,587: Line 6,587:


=={{header|Wren}}==
=={{header|Wren}}==
<lang ecmascript>var False = -1
<syntaxhighlight lang="ecmascript">var False = -1
var Maybe = 0
var Maybe = 0
var True = 1
var True = 1
Line 6,649: Line 6,649:
for (u in trits) System.write("%(t == u) ")
for (u in trits) System.write("%(t == u) ")
System.print()
System.print()
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 6,686: Line 6,686:
=={{header|Yabasic}}==
=={{header|Yabasic}}==
{{trans|BASIC256}}
{{trans|BASIC256}}
<lang yabasic>
<syntaxhighlight lang="yabasic">
tFalse = 0
tFalse = 0
tDontKnow = 1
tDontKnow = 1
Line 6,755: Line 6,755:
next a
next a
end
end
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>