Ternary logic: Difference between revisions

m
no edit summary
mNo edit summary
(86 intermediate revisions by 35 users not shown)
Line 93:
Note:   '''[[wp:Setun|Setun]]'''   (Сетунь) was a   [[wp:balanced ternary|balanced ternary]]   computer developed in 1958 at   [[wp:Moscow State University|Moscow State University]].   The device was built under the lead of   [[wp:Sergei Sobolev|Sergei Sobolev]]   and   [[wp:Nikolay Brusentsov|Nikolay Brusentsov]].   It was the only modern   [[wp:ternary computer|ternary computer]],   using three-valued [[wp:ternary logic|ternary logic]]
<br><br>
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">DEFINE TERNARY="BYTE"
DEFINE FALSE="0"
DEFINE MAYBE="1"
DEFINE TRUE="2"
 
PROC PrintT(TERNARY a)
IF a=FALSE THEN Print("F")
ELSEIF a=MAYBE THEN Print("?")
ELSE Print("T")
FI
RETURN
 
TERNARY FUNC NotT(TERNARY a)
RETURN (TRUE-a)
 
TERNARY FUNC AndT(TERNARY a,b)
IF a<b THEN RETURN (a) FI
RETURN (b)
 
TERNARY FUNC OrT(TERNARY a,b)
IF a>b THEN RETURN (a) FI
RETURN (b)
 
TERNARY FUNC IfThenT(TERNARY a,b)
IF a=TRUE THEN RETURN (b)
ELSEIF a=FALSE THEN RETURN (TRUE)
ELSEIF a+b>TRUE THEN RETURN (TRUE)
FI
RETURN (MAYBE)
 
TERNARY FUNC EquivT(TERNARY a,b)
IF a=b THEN RETURN (TRUE)
ELSEIF a=TRUE THEN RETURN (b)
ELSEIF b=TRUE THEN RETURN (a)
FI
RETURN (MAYBE)
 
PROC Main()
BYTE x,y,a,b,res
 
x=2 y=1
FOR a=FALSE TO TRUE
DO
res=NotT(a)
Position(x,y) y==+1
Print("not ") PrintT(a)
Print(" = ") PrintT(res)
OD
 
y==+1
FOR a=FALSE TO TRUE
DO
FOR b=FALSE TO TRUE
DO
res=AndT(a,b)
Position(x,y) y==+1
PrintT(a) Print(" and ") PrintT(b)
Print(" = ") PrintT(res)
OD
OD
 
y==+1
FOR a=FALSE TO TRUE
DO
FOR b=FALSE TO TRUE
DO
res=OrT(a,b)
Position(x,y) y==+1
PrintT(a) Print(" or ") PrintT(b)
Print(" = ") PrintT(res)
OD
OD
 
x=20 y=5
FOR a=FALSE TO TRUE
DO
FOR b=FALSE TO TRUE
DO
res=IfThenT(a,b)
Position(x,y) y==+1
Print("if ") PrintT(a)
Print(" then ") PrintT(b)
Print(" = ") PrintT(res)
OD
OD
 
y==+1
FOR a=FALSE TO TRUE
DO
FOR b=FALSE TO TRUE
DO
res=EquivT(a,b)
Position(x,y) y==+1
PrintT(a) Print(" equiv ") PrintT(b)
Print(" = ") PrintT(res)
OD
OD
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Ternary_logic.png Screenshot from Atari 8-bit computer]
<pre>
not F = T
not ? = ?
not T = F
 
F and F = F if F then F = T
F and ? = F if F then ? = T
F and T = F if F then T = T
? and F = F if ? then F = ?
? and ? = ? if ? then ? = ?
? and T = ? if ? then T = T
T and F = F if T then F = F
T and ? = ? if T then ? = ?
T and T = T if T then T = T
 
F or F = F F equiv F = T
F or ? = ? F equiv ? = ?
F or T = T F equiv T = F
? or F = ? ? equiv F = ?
? or ? = ? ? equiv ? = T
? or T = T ? equiv T = ?
T or F = T T equiv F = F
T or ? = T T equiv ? = ?
T or T = T T equiv T = T
</pre>
 
=={{header|Ada}}==
 
We first specify a package "Logic" for three-valued logic. Observe that predefined Boolean functions, "and" "or" and "not" are overloaded:
<langsyntaxhighlight Adalang="ada">package Logic is
type Ternary is (True, Unknown, False);
 
Line 111 ⟶ 238:
function To_Ternary(B: Boolean) return Ternary;
function Image(Value: Ternary) return Character;
end Logic;</langsyntaxhighlight>
 
Next, the implementation of the package:
 
<langsyntaxhighlight Adalang="ada">package body Logic is
-- type Ternary is (True, Unknown, False);
 
Line 176 ⟶ 303:
end Implies;
 
end Logic;</langsyntaxhighlight>
 
Finally, a sample program:
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO, Logic;
 
procedure Test_Tri_Logic is
Line 213 ⟶ 340:
Truth_Table(F => Equivalent'Access, Name => "Eq");
Truth_Table(F => Implies'Access, Name => "Implies");
end Test_Tri_Logic;</langsyntaxhighlight>
 
{{out}}
Line 239 ⟶ 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''.}}
'''File: Ternary_logic.a68'''
<langsyntaxhighlight lang="algol68"># -*- coding: utf-8 -*- #
 
INT trit width = 1, trit base = 3;
Line 337 ⟶ 464:
#true # (false, maybe, true )
)[@-1,@-1][INITINT a, INITINT b]
);</langsyntaxhighlight>'''File: Template_operators_logical_mixin.a68'''
<langsyntaxhighlight lang="algol68"># -*- coding: utf-8 -*- #
 
OP & = (LOGICAL a,b)LOGICAL: a AND b;
Line 362 ⟶ 489:
OP ~ = (LOGICAL a)LOGICAL: NOT a,
~= = (LOGICAL a,b)LOGICAL: a /= b; SCALAR!
FI#</langsyntaxhighlight>'''File: test_Ternary_logic.a68'''
<langsyntaxhighlight lang="algol68">#!/usr/local/bin/a68g --script #
# -*- coding: utf-8 -*- #
 
Line 432 ⟶ 559:
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("∨","OR", (TRIT a,b)TRIT: a OR b)</langsyntaxhighlight>
{{out}}
<pre>
Line 490 ⟶ 617:
⌈ | ⌈ | ⌈ | ⌈
</pre>
 
=={{header|Arturo}}==
 
Arturo's '':logical'' values inherently support ternary logic (<code>true</code>, <code>false</code> and <code>maybe</code>) and the corresponding logical operations.
 
<syntaxhighlight lang="rebol">vals: @[true maybe false]
 
loop vals 'v -> print ["NOT" v "=>" not? v]
print ""
loop vals 'v1 [
loop vals 'v2
-> print [v1 "AND" v2 "=>" and? v1 v2]
]
print ""
loop vals 'v1 [
loop vals 'v2
-> print [v1 "OR" v2 "=>" or? v1 v2]
]
print ""
loop vals 'v1 [
loop vals 'v2
-> print [v1 "XOR" v2 "=>" xor? v1 v2]
]</syntaxhighlight>
 
{{out}}
 
<pre>NOT true => false
NOT maybe => maybe
NOT false => true
 
true AND true => true
true AND maybe => maybe
true AND false => false
maybe AND true => maybe
maybe AND maybe => maybe
maybe AND false => false
false AND true => false
false AND maybe => false
false AND false => false
 
true OR true => true
true OR maybe => true
true OR false => true
maybe OR true => true
maybe OR maybe => maybe
maybe OR false => maybe
false OR true => true
false OR maybe => maybe
false OR false => false
 
true XOR true => false
true XOR maybe => maybe
true XOR false => true
maybe XOR true => maybe
maybe XOR maybe => maybe
maybe XOR false => maybe
false XOR true => true
false XOR maybe => maybe
false XOR false => false</pre>
 
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">Ternary_Not(a){
SetFormat, Float, 2.1
return Abs(a-1)
Line 511 ⟶ 698:
Ternary_Equiv(a,b){
return a=b?1:a=1?b:b=1?a:0.5
}</langsyntaxhighlight>
Examples:<langsyntaxhighlight AutoHotkeylang="autohotkey">aa:=[1,0.5,0]
bb:=[1,0.5,0]
 
Line 542 ⟶ 729:
StringReplace, Res, Res, 0, false, all
MsgBox % Res
return</langsyntaxhighlight>
{{out}}
<pre> Ternary_Not true = false
Line 588 ⟶ 775:
false Ternary_equiv false = true</pre>
 
 
=={{header|BASIC256}}==
{{trans|Liberty BASIC}}
<syntaxhighlight lang="lb">
global tFalse, tDontKnow, tTrue
tFalse = 0
tDontKnow = 1
tTrue = 2
 
print "Nombres cortos y largos para valores lógicos ternarios:"
for i = tFalse to tTrue
print shortName3$(i); " "; longName3$(i)
next i
print
 
print "Funciones de parámetro único"
print "x"; " "; "=x"; " "; "not(x)"
for i = tFalse to tTrue
print shortName3$(i); " "; shortName3$(i); " "; shortName3$(not3(i))
next i
print
 
print "Funciones de doble parámetro"
print "x";" ";"y";" ";"x AND y";" ";"x OR y";" ";"x EQ y";" ";"x XOR y"
for a = tFalse to tTrue
for b = tFalse to tTrue
print shortName3$(a); " "; shortName3$(b); " ";
print shortName3$(and3(a,b)); " "; shortName3$(or3(a,b));" ";
print shortName3$(eq3(a,b)); " "; shortName3$(xor3(a,b))
next b
next a
end
 
function and3(a,b)
if a < b then return a else return b
end function
 
function or3(a,b)
if a > b then return a else return b
end function
 
function eq3(a,b)
begin case
case a = tDontKnow or b = tDontKnow
return tDontKnow
case a = b
return tTrue
else
return tFalse
end case
end function
 
function xor3(a,b)
return not3(eq3(a,b))
end function
 
function not3(b)
return 2-b
end function
 
function shortName3$(i)
return mid("F?T", i+1, 1)
end function
 
function longName3$(i)
begin case
case i = 1
return "Don't know"
case i = 2
return "True"
else
return "False"
end case
end function
</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de Liberty BASIC.
</pre>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> INSTALL @lib$ + "CLASSLIB"
REM Create a ternary class:
Line 636 ⟶ 902:
PRINT "TRUE EQV TRUE = " FN(mytrit.teqv)("TRUE","TRUE")
PROC_discard(mytrit{})</langsyntaxhighlight>
{{out}}
<pre>
Line 667 ⟶ 933:
MAYBE EQV TRUE = MAYBE
TRUE EQV TRUE = TRUE
</pre>
 
=={{header|Bruijn}}==
Direct translations of the truth tables to lambda calculus. The operators could be golfed significantly. If you do so, please add them here!
 
For applications of Ternary logic, see bruijn's [[Balanced_ternary#Bruijn|balanced ternary]] implementation.
<syntaxhighlight lang="bruijn">
true [[[0]]]
 
maybe [[[1]]]
 
false [[[2]]]
 
¬‣ [0 true maybe false]
 
…⋀… [[1 (0 1 1 1) (0 0 0 1) (0 0 0 0)]]
 
…⋁… [[1 (0 0 0 0) (0 1 0 0) (0 1 1 1)]]
 
…⊃… [[1 (0 true 0 1) (0 true 1 1) (0 1 1 1)]]
 
…≡… [[1 (0 true 0 1) (0 1 1 1) (0 0 0 0)]]
 
# --- result samples ---
 
:import std/List .
 
main [[inp <> "=" <> !res ++ "\n"] <++> (cross3 ops trits trits)]
!‣ [0 "false" "maybe" "true"]
…<>… [[1 ++ " " ++ 0]]
inp 0 [[~1 <> (0 [[!1 <> (0 [[!1]])]])]]
res ^(^0) ^(~0) ^(~(~0))
ops (…⋀… : "and") : ((…⋁… : "or") : ((…⊃… : "if") : {}(…≡… : "equiv")))
trits true : (maybe : {}false)
</syntaxhighlight>
 
{{out}}
<pre>
and true true = true
and true maybe = maybe
and true false = false
and maybe true = maybe
and maybe maybe = maybe
and maybe false = false
and false true = false
and false maybe = false
and false false = false
or true true = true
or true maybe = true
or true false = true
or maybe true = true
or maybe maybe = maybe
or maybe false = maybe
or false true = true
or false maybe = maybe
or false false = false
if true true = true
if true maybe = true
if true false = true
if maybe true = maybe
if maybe maybe = maybe
if maybe false = true
if false true = false
if false maybe = maybe
if false false = true
equiv true true = true
equiv true maybe = maybe
equiv true false = false
equiv maybe true = maybe
equiv maybe maybe = maybe
equiv maybe false = maybe
equiv false true = false
equiv false maybe = maybe
equiv false false = true
</pre>
 
=={{header|C}}==
===Implementing logic using lookup tables===
<langsyntaxhighlight lang="c">#include <stdio.h>
typedef enum {
Line 741 ⟶ 1,081:
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 789 ⟶ 1,129:
 
===Using functions===
<langsyntaxhighlight lang="c">#include <stdio.h>
 
typedef enum { t_F = -1, t_M, t_T } trit;
Line 824 ⟶ 1,164:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>[Not]
Line 865 ⟶ 1,205:
the result is randomly sampled to true or false according to the chance.
(This description is definitely very confusing perhaps).
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 919 ⟶ 1,259:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">using System;
 
/// <summary>
/// Extension methods on nullable bool.
/// </summary>
/// <remarks>
/// The operators !, & and | are predefined.
/// </remarks>
public static class NullableBoolExtension
{
public static bool? Implies(this bool? left, bool? right)
{
return !left | right;
}
 
public static bool? IsEquivalentTo(this bool? left, bool? right)
{
return left.HasValue && right.HasValue ? left == right : default(bool?);
}
 
public static string Format(this bool? value)
{
return value.HasValue ? value.Value.ToString() : "Maybe";
}
}
 
public class Program
{
private static void Main()
{
var values = new[] { true, default(bool?), false };
 
foreach (var left in values)
{
Console.WriteLine("¬{0} = {1}", left.Format(), (!left).Format());
foreach (var right in values)
{
Console.WriteLine("{0} & {1} = {2}", left.Format(), right.Format(), (left & right).Format());
Console.WriteLine("{0} | {1} = {2}", left.Format(), right.Format(), (left | right).Format());
Console.WriteLine("{0} → {1} = {2}", left.Format(), right.Format(), left.Implies(right).Format());
Console.WriteLine("{0} ≡ {1} = {2}", left.Format(), right.Format(), left.IsEquivalentTo(right).Format());
}
}
}
}</syntaxhighlight>
{{out}}
<pre>¬True = False
True & True = True
True | True = True
True → True = True
True ≡ True = True
True & Maybe = Maybe
True | Maybe = True
True → Maybe = Maybe
True ≡ Maybe = Maybe
True & False = False
True | False = True
True → False = False
True ≡ False = False
¬Maybe = Maybe
Maybe & True = Maybe
Maybe | True = True
Maybe → True = True
Maybe ≡ True = Maybe
Maybe & Maybe = Maybe
Maybe | Maybe = Maybe
Maybe → Maybe = Maybe
Maybe ≡ Maybe = Maybe
Maybe & False = False
Maybe | False = Maybe
Maybe → False = Maybe
Maybe ≡ False = Maybe
¬False = True
False & True = False
False | True = True
False → True = True
False ≡ True = False
False & Maybe = False
False | Maybe = Maybe
False → Maybe = True
False ≡ Maybe = Maybe
False & False = False
False | False = False
False → False = True
False ≡ False = True</pre>
 
=={{header|C++}}==
Essentially the same logic as the [[#Using functions|Using functions]] implementation above, but using class-based encapsulation and overridden operators.
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <stdlib.h>
 
Line 996 ⟶ 1,423:
show_op(==);
return EXIT_SUCCESS;
}</langsyntaxhighlight>
{{out}}
<pre>! ----
Line 1,026 ⟶ 1,453:
? | ? ? ?
F | F ? T</pre>
 
=={{header|C sharp|C#}}==
<lang csharp>using System;
 
/// <summary>
/// Extension methods on nullable bool.
/// </summary>
/// <remarks>
/// The operators !, & and | are predefined.
/// </remarks>
public static class NullableBoolExtension
{
public static bool? Implies(this bool? left, bool? right)
{
return !left | right;
}
 
public static bool? IsEquivalentTo(this bool? left, bool? right)
{
return left.HasValue && right.HasValue ? left == right : default(bool?);
}
 
public static string Format(this bool? value)
{
return value.HasValue ? value.Value.ToString() : "Maybe";
}
}
 
public class Program
{
private static void Main()
{
var values = new[] { true, default(bool?), false };
 
foreach (var left in values)
{
Console.WriteLine("¬{0} = {1}", left.Format(), (!left).Format());
foreach (var right in values)
{
Console.WriteLine("{0} & {1} = {2}", left.Format(), right.Format(), (left & right).Format());
Console.WriteLine("{0} | {1} = {2}", left.Format(), right.Format(), (left | right).Format());
Console.WriteLine("{0} → {1} = {2}", left.Format(), right.Format(), left.Implies(right).Format());
Console.WriteLine("{0} ≡ {1} = {2}", left.Format(), right.Format(), left.IsEquivalentTo(right).Format());
}
}
}
}</lang>
{{out}}
<pre>¬True = False
True & True = True
True | True = True
True → True = True
True ≡ True = True
True & Maybe = Maybe
True | Maybe = True
True → Maybe = Maybe
True ≡ Maybe = Maybe
True & False = False
True | False = True
True → False = False
True ≡ False = False
¬Maybe = Maybe
Maybe & True = Maybe
Maybe | True = True
Maybe → True = True
Maybe ≡ True = Maybe
Maybe & Maybe = Maybe
Maybe | Maybe = Maybe
Maybe → Maybe = Maybe
Maybe ≡ Maybe = Maybe
Maybe & False = False
Maybe | False = Maybe
Maybe → False = Maybe
Maybe ≡ False = Maybe
¬False = True
False & True = False
False | True = True
False → True = True
False ≡ True = False
False & Maybe = False
False | Maybe = Maybe
False → Maybe = True
False ≡ Maybe = Maybe
False & False = False
False | False = False
False → False = True
False ≡ False = True</pre>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun tri-not (x) (- 1 x))
(defun tri-and (&rest x) (apply #'* x))
(defun tri-or (&rest x) (tri-not (apply #'* (mapcar #'tri-not x))))
Line 1,145 ⟶ 1,485:
(print-table #'tri-or "OR")
(print-table #'tri-imply "IMPLY")
(print-table #'tri-eq "EQUAL")</langsyntaxhighlight>
{{out}}
<pre>NOT:
Line 1,182 ⟶ 1,522:
=={{header|D}}==
Partial translation of a C entry:
<langsyntaxhighlight lang="d">import std.stdio;
 
struct Trit {
Line 1,249 ⟶ 1,589:
showOperation!"=="("Equiv");
showOperation!"==>"("Imply");
}</langsyntaxhighlight>
{{out}}
<pre>[Not]
Line 1,292 ⟶ 1,632:
 
=={{header|Delphi}}==
<langsyntaxhighlight lang="delphi">unit TrinaryLogic;
 
interface
Line 1,347 ⟶ 1,687:
end;
 
end.</langsyntaxhighlight>
 
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
<langsyntaxhighlight lang="delphi">type TriBool = (tbFalse, tbMaybe, tbTrue);</langsyntaxhighlight>
and defining a set of constants implementing the above tables:
<langsyntaxhighlight lang="delphi">const
tvl_not: array[TriBool] = (tbTrue, tbMaybe, tbFalse);
tvl_and: array[TriBool, TriBool] = (
Line 1,376 ⟶ 1,716:
(tbFalse, tbMaybe, tbTrue),
);
</syntaxhighlight>
</lang>
 
That's no real fun, but lookup can then be done with
<langsyntaxhighlight lang="delphi">Result := tvl_and[A, B];</langsyntaxhighlight>
=={{header|Elena}}==
ELENA 3.2.1 :
<lang elena>import extensions.
import system'routines.
import system'collections.
 
=={{header|EasyLang}}==
{{trans|FreeBASIC}}
<syntaxhighlight>
sym$[] = [ "F" "?" "T" ]
arrbase sym$[] -1
#
func tnot x .
return -x
.
func tand x y .
if x > y
return tand y x
.
return x
.
func tor x y .
if x < y
return tor y x
.
return x
.
func teqv x y .
return x * y
.
func timp x y .
if -y > x
return -y
.
return x
.
print " (AND) ( OR) (EQV) (IMP) (NOT)"
print " F ? T F ? T F ? T F ? T "
print " -----------------------------------------"
for i = -1 to 1
o$ = " " & sym$[i] & " | "
o$ &= sym$[tand -1 i] & " " & sym$[tand 0 i] & " " & sym$[tand 1 i]
o$ &= " "
o$ &= sym$[tor -1 i] & " " & sym$[tor 0 i] & " " & sym$[tor 1 i]
o$ &= " "
o$ &= sym$[timp -1 i] & " " & sym$[timp 0 i] & " " & sym$[timp 1 i]
o$ &= " "
o$ &= sym$[timp -1 i] & " " & sym$[timp 0 i] & " " & sym$[timp 1 i]
o$ &= " " & sym$[tnot i]
print o$
.
</syntaxhighlight>
 
=={{header|Elena}}==
ELENA 6.x :
<syntaxhighlight lang="elena">import extensions;
import system'routines;
import system'collections;
sealed class Trit
{
bool _value.;
bool cast() = _value.;
constructor(object v)
sealed explicit object:v
[{
if (v _value :!= v bool.nil)
] {
_value := cast bool(v);
}
}
Trit equivalent(b)
{
var val2 := cast bool(b) \ back(nil);
 
if (val2 != nil && _value != nil)
type<Trit> equivalent : b
{
= _value equal(b bool) \ back:nil.
^ _value.equal(val2)
};
 
^ nilValue;
type<Trit> inverted
}
= _value inverted \ back:nil.
type<Trit> and : bInverted
= _value.Inverted \ back(nilValue);
[
if ($nil == _value)
Trit [and(b)
{
^ b and:nil \ back:nil.
if (nil ];== _value)
[{
^ _value b.and:$(b boolnil) \ back:nil.(nilValue)
]}
] else
{
^ _value.and(b) \ back(nilValue)
type<Trit> or : b
[ }
}
if ($nil == _value)
[
Trit or(b)
^ b or:nil \ back:nil.
];{
if (nil [== _value)
{
^ _value or:$(b bool) \ back:nil.
^ b.or(nilValue) \ back(nilValue)
]
] }
else
type<Trit> implies : b{
= $self inverted;^ _value.or:(b.) \ back(nilValue)
}
}
literal = _value literal \ back:"maybe".
Trit implies(b)
= self.Inverted.or(b);
string toPrintable() = _value.toPrintable() \ back("maybe");
}
 
public program()
program =
{
[
listList<Trit> values := (new Trit[]{true, nilnilValue, false).};
values .forEach(::(left)
[{
console .printLine("¬",left," = ", left inverted.Inverted).;
values .forEach(::(right)
[{
console .printLine(left, " & ", right, " = ", left && right).;
console .printLine(left, " | ", right, " = ", left || right).;
console .printLine(left, " → ", right, " = ", left .implies:(right).);
console .printLine(left, " ≡ ", right, " = ", left .equivalent:(right).)
].}
].}
}</syntaxhighlight>
].</lang>
{{out}}
<pre>
Line 1,490 ⟶ 1,892:
 
=={{header|Erlang}}==
<langsyntaxhighlight lang="erlang">% Implemented by Arjun Sunel
-module(ternary).
-export([main/0, nott/1, andd/2,orr/2, then/2, equiv/2]).
Line 1,564 ⟶ 1,966:
io: format("~s\n", [B])
end.
</syntaxhighlight>
</lang>
 
=={{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''.
 
<langsyntaxhighlight lang="factor">! rosettacode/ternary/ternary.factor
! http://rosettacode.org/wiki/Ternary_logic
USING: combinators kernel ;
Line 1,609 ⟶ 2,011:
{ m [ >trit drop m ] }
{ f [ tnot ] }
} case ;</langsyntaxhighlight>
 
Example use:
<langsyntaxhighlight lang="factor">( scratchpad ) CONSTANT: trits { t m f }
( scratchpad ) trits [ tnot ] map .
{ f m t }
Line 1,622 ⟶ 2,024:
{ { f m t } { m m m } { t m f } }
( scratchpad ) trits [ trits swap [ t= ] curry map ] map .
{ { t m f } { m m m } { f m t } }</langsyntaxhighlight>
 
 
=={{header|Forth}}==
{{works with|gforth|0.7.3}}
 
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.
 
<syntaxhighlight lang="forth">1 constant maybe
 
: tnot dup maybe <> if invert then ;
: tand and ;
: tor or ;
: tequiv 2dup and rot tnot rot tnot and or ;
: timply tnot tor ;
: txor tequiv tnot ;
 
: t. C" TF?" 2 + + c@ emit ;
 
: table2. ( xt -- )
cr ." T F ?"
cr ." --------"
2 true DO
cr I t. ." | "
2 true DO
dup I J rot execute t. ." "
LOOP
LOOP DROP ;
 
: table1. ( xt -- )
2 true DO
CR I t. ." | "
dup I swap execute t.
LOOP DROP ;
 
CR ." [NOT]" ' tnot table1. CR
CR ." [AND]" ' tand table2. CR
CR ." [OR]" ' tor table2. CR
CR ." [XOR]" ' txor table2. CR
CR ." [IMPLY]" ' timply table2. CR
CR ." [EQUIV]" ' tequiv table2. CR
</syntaxhighlight>
 
{{out}}
<pre>[NOT]
T | F
F | T
? | ?
 
[AND]
T F ?
--------
T | T F ?
F | F F F
? | ? F ?
 
[OR]
T F ?
--------
T | T T T
F | T F ?
? | T ? ?
 
[XOR]
T F ?
--------
T | F T ?
F | T F ?
? | ? ? ?
 
[IMPLY]
T F ?
--------
T | T F ?
F | T T T
? | T ? ?
 
[EQUIV]
T F ?
--------
T | T F ?
F | F T ?
? | ? ? ?
</pre>
 
As Forth is a concatenative language, ternary logic use appears seamless:
<pre>: optimist CR or if ." yes !" else ." no..." then ; ok
true maybe optimist
yes ! ok
maybe false optimist
yes ! ok
maybe maybe optimist
yes ! ok
false false optimist
no... ok
</pre>
 
 
=={{header|Fortran}}==
 
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/" -*-
!Compilation started at Mon May 20 23:05:46
Line 1,725 ⟶ 2,223:
 
end program ternaryLogic
</syntaxhighlight>
</lang>
 
=={{header|Free Pascal}}==
Free Pascal version with lookup.
Note equivalence and implication are used as proof, they are solved using the basic set instead of a lookup.
<lang pascal>program ternarytests;
Note Since we use a balanced range -1,0,1 multiplication equals EQU
{$mode objfpc}
<syntaxhighlight lang="pascal">{$mode objfpc}
unit ternarylogic;
 
interface
type
{ ternary type, balanced }
trit = (FtFalse=-1, UtMaybe=0, TtTrue=1);
 
{ ternary operators }
{ equivalence = multiplication }
operator * (const a,b:trit):trit;
operator and (const a,b:trit):trit;inline;
operator or (const a,b:trit):trit;inline;
operator not (const a:trit):trit;inline;
operator xor (const a,b:trit):trit;
{ imp ==>}
operator >< (const a,b:trit):trit;
 
implementation
 
operator and (const a,b:trit):trit;inline;
const lookupAnd:array[trit,trit] of trit =
((FtFalse,FtFalse,FtFalse),(F,U,U),(F,U,T));
(tFalse,tMaybe,tMaybe),
(tFalse,tMaybe,tTrue));
begin
Result:= LookupAnd[a,b];
end;
operator or (const a,b:trit):trit;inline;
const lookupOr:array[trit,trit] of trit =
((FtFalse,UtMaybe,TtTrue),(U,U,T),(T,T,T));
(tMaybe,tMaybe,tTrue),
(tTrue,tTrue,tTrue));
begin
Result := LookUpOr[a,b];
end;
 
operator not (const a:trit):trit;inline;
const LookupNot:array[trit] of trit =(TtTrue,UtMaybe,FtFalse);
begin
Result:= LookUpNot[a];
end;
operator xor (const a,b:trit):trit;inline;
const LookupXor:array[trit,trit] of trit =
((F,U,T),(U,U,U),(T,U,F));
begin
Result := LookupXor[a,b];
end;
operator xor (const a,b:trit):trit;
{ using one of the free set operators for EQU }
operator >< (const a,bLookupXor:array[trit):,trit;inline;] of trit =
((tFalse,tMaybe,tTrue),
const LookupXor:array[trit,trit] of trit =
(tMaybe,tMaybe,tMaybe),
((T,U,F),(U,U,U),(F,U,T));
(tTrue,tMaybe,tFalse));
begin
Result := LookupXor[a,b];
end;
 
{ using the free power operator for* IMP(const }a,b:trit):trit;
operator ** (const a,b:trit):trit;inline;
const LookupXor:array[trit,trit] of trit =
((T,T,T),(U,U,T),(F,U,T));
begin
Resultresult := LookupXor[not (a, xor b]);
end;
 
{ imp ==>}
{ or if you don't like the two above, use functions }
functionoperator >< EQU(const a,b:trit):trit;inline;
begin
Result result := NOT not(a) XORor b) ;
end;
end.
</syntaxhighlight>
function IMP(const a,b:trit):trit;inline;
<syntaxhighlight lang="pascal">program ternarytests;
begin
{$mode objfpc}
Result := NOT(a) OR b;
uses
end;
ternarylogic;
begin
writeln(' a AND b');
writeln('__FUTF':7,'U':7, 'T':7);
writeln('F|',FtFalse and FtFalse:7,FtFalse and UtMaybe:7,FtFalse and TtTrue:7);
writeln('U|',UtMaybe and FtFalse:7,UtMaybe and UtMaybe:7,UtMaybe and TtTrue:7);
writeln('T|',TtTrue and FtFalse:7,TtTrue and UtMaybe:7,TtTrue and TtTrue:7);
writeln;
writeln(' a OR b');
writeln('__FUTF':7,'U':7, 'T':7);
writeln('F|',FtFalse or FtFalse:7,FtFalse or UtMaybe:7,FtFalse or TtTrue:7);
writeln('U|',UtMaybe or FtFalse:7,UtMaybe or UtMaybe:7,UtMaybe or TtTrue:7);
writeln('T|',TtTrue or FtFalse:7,TtTrue or UtMaybe:7,TtTrue or TtTrue:7);
writeln;
writeln(' NOT a');
writeln('__FUTF|',not tFalse:7);
writeln('FU|',not FtMaybe:7);
writeln('UT|',not UtTrue:7);
writeln('T|',not T);
writeln;
writeln(' a XOR b');
writeln('__FUTF':7,'U':7, 'T':7);
writeln('F|',FtFalse xor FtFalse:7,FtFalse xor UtMaybe:7,FtFalse xor TtTrue:7);
writeln('U|',UtMaybe xor FtFalse:7,UtMaybe xor UtMaybe:7,UtMaybe xor TtTrue:7);
writeln('T|',TtTrue xor FtFalse:7,TtTrue xor UtMaybe:7,TtTrue xor TtTrue:7);
writeln;
 
writeln('equality/equivalence NOTand (a XOR b) -> equivalentmultiplication');
writeln('__FUTF':7,'U':7, 'T':7);
writeln('F|',not(F xortFalse F)* tFalse:7,not(FtFalse xor* U)tMaybe:7,not(F xortFalse * T)tTrue:7);
writeln('U|',not(U xortMaybe F)* tFalse:7,not(UtMaybe xor* U)tMaybe:7,not(UtMaybe xor* T)tTrue:7);
writeln('T|',not(T xortTrue F)* tFalse:7,not(T xortTrue U)* tMaybe:7,not(T xortTrue * T)tTrue:7);
writeln;
 
writeln('IMP. usinga.k.a. IfThen ->< asnot(a) EQU ->or equivalenceb');
writeln('__FUTF':7,'U':7, 'T':7);
writeln('FT|',FtTrue >< FtTrue:7,FtTrue >< UtMaybe:7,FtTrue >< TtFalse:7);
writeln('U|',UtMaybe >< FtTrue:7,UtMaybe >< UtMaybe:7,UtMaybe >< TtFalse:7);
writeln('TF|',TtFalse >< FtTrue:7,T tFalse >< UtMaybe:7,TtFalse >< TtFalse:7);
writeln;
 
writeln(' NOT(a) OR b -> IMP. a.k.a. IfThen');
writeln('T|',(not T) or T,(not T) or U,(not T) or F);
writeln('U|',(not U) or T,(not U) or U,(not U) or F);
writeln('F|',(not F) or T,(not F) or U,(not F) or F);
writeln;
end.</syntaxhighlight>
writeln(' using ** as IMP a.k.a. IfThen');
writeln('T|',T ** T,T ** U,T ** F);
writeln('U|',U ** T,U ** U,U ** F);
writeln('F|',F ** T,F ** U,F ** F);
 
end.</lang>
<pre>
Output:
a AND b
F U T
__FUT
F|tFalse tFalse tFalse
F|FFF
U|tFalse tMaybe tMaybe
U|FUU
T|tFalse tMaybe tTrue
T|FUT
 
a OR b
F U T
__FUT
F|tFalse tMaybe tTrue
F|FUT
U|tMaybe tMaybe tTrue
U|UUT
T|tTrue tTrue tTrue
T|TTT
 
NOT a
F|tTrue
__FUT
U|tMaybe
F|T
T|tFalse
U|U
T|F
 
a XOR b
F U T
__FUT
F|tFalse tMaybe tTrue
F|FUT
U|tMaybe tMaybe tMaybe
U|UUU
T|tTrue tMaybe tFalse
T|TUF
 
equality/equivalence and multiplication
F U T
F|tTrue tMaybe tFalse
U|tMaybe tMaybe tMaybe
T|tFalse tMaybe tTrue
 
IMP. a.k.a. IfThen -> not(a) or b
F U T
T|tTrue tMaybe tFalse
U|tTrue tMaybe tMaybe
F|tTrue tTrue tTrue
</pre>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">enum trit
F=-1, M=0, T=1
end enum
 
dim as string symbol(-1 to 1) = {"F", "?", "T"}, outstr
dim as trit i
 
operator not ( x as trit ) as trit
return -x
end operator
 
operator and (x as trit, y as trit) as trit
if x>y then return y and x
return x
end operator
 
operator or ( x as trit, y as trit ) as trit
if x<y then return y or x
return x
end operator
 
operator eqv ( x as trit, y as trit ) as trit
return x*y
end operator
 
operator imp ( x as trit, y as trit ) as trit
if -y>x then return -y
return x
end operator
 
print " (AND) ( OR) (EQV) (IMP) (NOT)"
print " F ? T F ? T F ? T F ? T "
print " -------------------------------------------------"
for i = F to T
outstr = " "+symbol(i)+" | "
outstr += symbol(F and i) + " " + symbol(M and i) + " " + symbol(T and i)
outstr += " "
outstr += symbol(F or i) + " " + symbol(M or i) + " " + symbol(T or i)
outstr += " "
outstr += symbol(F eqv i) + " " + symbol(M eqv i) + " " + symbol(T eqv i)
outstr += " "
outstr += symbol(F imp i) + " " + symbol(M imp i) + " " + symbol(T imp i)
outstr += " " + symbol(not(i))
print outstr
next i</syntaxhighlight>
<pre>
(AND) ( OR) (EQV) (IMP) (NOT)
F ? T F ? T F ? T F ? T
-------------------------------------------------
F | F F F F ? T T ? F T T T T
? | F ? ? ? ? T ? ? ? ? ? T ?
T | F ? T T T T F ? T F ? T F
</pre>
 
<!--
=={{header|Fōrmulæ}}==
 
In [http://wiki.formulae.org/Finite-valued_logic this] page you can see the solution of this task.
NOT (a XOR b) -> equivalent
__FUT
F|TUF
U|UUU
T|FUT
 
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text ([http://wiki.formulae.org/Editing_F%C5%8Drmul%C3%A6_expressions more info]). Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation &mdash;i.e. XML, JSON&mdash; they are intended for transportation effects more than visualization and edition.
using >< as EQU -> equivalence
__FUT
F|TUF
U|UUU
T|FUT
 
The option to show Fōrmulæ programs and their results is showing images. Unfortunately images cannot be uploaded in Rosetta Code.
NOT(a) OR b -> IMP. a.k.a. IfThen
T|TUF
U|TUU
F|TTT
 
The solution shown uses [https://en.wikipedia.org/wiki/Finite-valued_logic finite-valued logic], where the n-valued logic can be represented as n equally spaced values between 0 (pure false) and 1 (pure true). As an example, the traditional logic values are represented as 0 and 1, and ternary logic is represented with the values 0 (false), 1/2 (maybe) and 1 (true), and so on.
using ** as IMP a.k.a. IfThen
T|TUF
U|TUU
F|TTT</pre>
 
The solution also shows how to ''redefine'' the logic operations, and how to show the values and the operations using colors.
-->
 
=={{header|Go}}==
Go has four operators for the bool type: ==, &&, ||, and !.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 1,969 ⟶ 2,525:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,013 ⟶ 2,569:
=={{header|Groovy}}==
Solution:
<langsyntaxhighlight lang="groovy">enum Trit {
TRUE, MAYBE, FALSE
Line 2,030 ⟶ 2,586:
Trit imply(Trit that) { this.nand(that.not()) }
Trit equiv(Trit that) { this.and(that).or(this.nor(that)) }
}</langsyntaxhighlight>
 
Test:
<langsyntaxhighlight lang="groovy">printf 'AND\n '
Trit.values().each { b -> printf ('%6s', b) }
println '\n ----- ----- -----'
Line 2,072 ⟶ 2,628:
Trit.values().each { b -> printf ('%6s', a.equiv(b)) }
println()
}</langsyntaxhighlight>
 
{{out}}
Line 2,112 ⟶ 2,668:
All operations given in terms of NAND, the functionally-complete operation.
 
<langsyntaxhighlight Haskelllang="haskell">import Prelude hiding (Bool(..), not, (&&), (||), (==))
 
main = mapM_ (putStrLn . unlines . map unwords)
Line 2,148 ⟶ 2,704:
where header = map (:[]) (take ((length $ head xs) - 1) ['A'..]) ++ [name]
 
pad s = s ++ replicate (5 - length s) ' '</langsyntaxhighlight>
 
{{out}}
Line 2,208 ⟶ 2,764:
 
 
<langsyntaxhighlight Iconlang="icon">$define TRUE 1
$define FALSE -1
$define UNKNOWN 0
Line 2,269 ⟶ 2,825:
procedure xor3(a,b) #: xor of two trits or error if invalid
return not3(eq3(a,b))
end</langsyntaxhighlight>
 
{{libheader|Icon Programming Library}}
Line 2,320 ⟶ 2,876:
maybe: 0.5
 
<langsyntaxhighlight lang="j">not=: -.
and=: <.
or =: >.
if =: (>. -.)"0~
eq =: (<.&-. >. <.)"0</langsyntaxhighlight>
 
Example use:
 
<langsyntaxhighlight lang="j"> not 0 0.5 1
1 0.5 0
 
Line 2,349 ⟶ 2,905:
1 0.5 0
0.5 0.5 0.5
0 0.5 1</langsyntaxhighlight>
 
Note that this implementation is a special case of "[[wp:fuzzy logic|fuzzy logic]]" (using a limited set of values).
 
Note that while <code>>.</code> and <code><.</code> could be used for boolean operations instead of J's <code>+.</code> and <code>*.</code>, the identity elements for >. and <. are not boolean1 valuesand 0, but are negative and positive infinity. See also: [[wp:Boolean ring|Boolean ring]]
 
Note that we might instead define values between 0 and 1 to represent independent probabilities:
 
<langsyntaxhighlight Jlang="j">not=: -.
and=: *
or=: *&.-.
if =: (or -.)"0~
eq =: (*&-. or *)"0</langsyntaxhighlight>
 
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):
 
<langsyntaxhighlight Jlang="j"> not 0 0.5 1
1 0.5 0
 
Line 2,386 ⟶ 2,942:
1 0.5 0
0.5 0.4375 0.5
0 0.5 1</langsyntaxhighlight>
 
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:
 
<langsyntaxhighlight Jlang="j">and=: *.
or=: +.</langsyntaxhighlight>
 
And, the boolean result tables would look like this:
 
<langsyntaxhighlight Jlang="j"> 0 0.5 1 and/ 0 0.5 1
0 0 0
0 0.5 1
Line 2,403 ⟶ 2,959:
0 0.5 1
0.5 0.5 0.5
1 0.5 1</langsyntaxhighlight>
 
=={{header|Java}}==
{{works with|Java|1.5+}}
<langsyntaxhighlight lang="java5">public class Logic{
public static enum Trit{
TRUE, MAYBE, FALSE;
Line 2,474 ⟶ 3,030:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>not TRUE: FALSE
Line 2,492 ⟶ 3,048:
Let's use the trit already available in JavaScript:
true, false (both boolean) and undefined…
<langsyntaxhighlight JavaScriptlang="javascript">var L3 = new Object();
 
L3.not = function(a) {
Line 2,525 ⟶ 3,081:
return L3.and(L3.ifThen(a, b), L3.ifThen(b, a));
}
</syntaxhighlight>
</lang>
… and try these:
<syntaxhighlight lang="text">
L3.not(true) // false
L3.not(var a) // undefined
Line 2,538 ⟶ 3,094:
 
L3.iff(a, 2 == 2) // undefined
</syntaxhighlight>
</lang>
Here is a compact, highly readable solution that uses undefined for the third value of the trit
<syntaxhighlight lang="javascript">
nand = (a, b) => (a == false || b == false) ? true : (a == undefined || b == undefined) ? undefined : false
not = (a) => nand(a, a)
and = (a, b) => not(nand(a, b))
or = (a, b) => nand(not(a), not(b))
nor = (a, b) => not(or(a, b))
implies = (a, b) => nand(a, not(b))
iff = (a, b) => or(and(a, b), nor(a, b))
xor = (a, b) => not(iff(a, b))
</syntaxhighlight>
... to test it
<syntaxhighlight lang="javascript">
trit = [false, undefined, true]
functor = {nand, and, or, nor, implies, iff, xor}
display = {nand: '⊼', and: '∧', or: '∨', nor: '⊽', implies: '→', iff: '↔', xor: '⊻', not: '¬', false: 'F', undefined: '?', true: 'T'}
 
log = 'NOT\n';
for (let a of trit) log += `${display.not}${display[a]} = ${display[not(a)]}\n`
 
log += '\nNAND AND OR NOR IMPLIES IFF XOR'
for (let a of trit) {
for (let b of trit) {
log += "\n"
for (let op in functor) log += `${display[a]} ${display[op]} ${display[b]} = ${display[functor[op](a, b)]} `
}
}
console.log(log)
</syntaxhighlight>
...Output:
<syntaxhighlight lang="text">
NOT
¬F = T
¬? = ?
¬T = F
 
NAND AND OR NOR IMPLIES IFF XOR
F ⊼ F = T F ∧ F = F F ∨ F = F F ⊽ F = T F → F = T F ↔ F = T F ⊻ F = F
F ⊼ ? = T F ∧ ? = F F ∨ ? = ? F ⊽ ? = ? F → ? = T F ↔ ? = ? F ⊻ ? = ?
F ⊼ T = T F ∧ T = F F ∨ T = T F ⊽ T = F F → T = T F ↔ T = F F ⊻ T = T
? ⊼ F = T ? ∧ F = F ? ∨ F = ? ? ⊽ F = ? ? → F = ? ? ↔ F = ? ? ⊻ F = ?
? ⊼ ? = ? ? ∧ ? = ? ? ∨ ? = ? ? ⊽ ? = ? ? → ? = ? ? ↔ ? = ? ? ⊻ ? = ?
? ⊼ T = ? ? ∧ T = ? ? ∨ T = T ? ⊽ T = F ? → T = T ? ↔ T = ? ? ⊻ T = ?
T ⊼ F = T T ∧ F = F T ∨ F = T T ⊽ F = F T → F = F T ↔ F = F T ⊻ F = T
T ⊼ ? = ? T ∧ ? = ? T ∨ ? = T T ⊽ ? = F T → ? = ? T ↔ ? = ? T ⊻ ? = ?
T ⊼ T = F T ∧ T = T T ∨ T = T T ⊽ T = F T → T = T T ↔ T = T T ⊻ T = F
</syntaxhighlight>
 
=={{header|jq}}==
Line 2,544 ⟶ 3,147:
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. <langsyntaxhighlight lang="jq">def ternary_nand(a; b):
if a == false or b == false then true
elif a == "maybe" or b == "maybe" then "maybe"
Line 2,576 ⟶ 3,179:
display_equiv( (false, "maybe", true ); (false, "maybe", true) ),
"etc etc"
</syntaxhighlight>
</lang>
{{out}}
<pre>"false and false is false"
Line 2,602 ⟶ 3,205:
{{works with|Julia|0.6}}
 
<langsyntaxhighlight lang="julia">@enum Trit False Maybe True
const trits = (False, Maybe, True)
 
Line 2,628 ⟶ 3,231:
for a in trits
println(join(@sprintf("%10s ≡ %5s is %5s", a, b, a ≡ b) for b in trits))
end</langsyntaxhighlight>
 
{{out}}
Line 2,649 ⟶ 3,252:
Maybe ≡ False is Maybe Maybe ≡ Maybe is Maybe Maybe ≡ True is Maybe
True ≡ False is False True ≡ Maybe is Maybe True ≡ True is True</pre>
 
 
== Alternative version ==
{{works with|Julia|0.7}}
 
With Julia 1.0 and the new type <tt>missing</tt>, three-value logic is implemented by default
<syntaxhighlight lang="julia"># built-in: true, false and missing
 
using Printf
 
const tril = (true, missing, false)
 
@printf("\n%8s | %8s\n", "A", "¬A")
for A in tril
@printf("%8s | %8s\n", A, !A)
end
 
@printf("\n%8s | %8s | %8s\n", "A", "B", "A ∧ B")
for (A, B) in Iterators.product(tril, tril)
@printf("%8s | %8s | %8s\n", A, B, A & B)
end
 
@printf("\n%8s | %8s | %8s\n", "A", "B", "A ∨ B")
for (A, B) in Iterators.product(tril, tril)
@printf("%8s | %8s | %8s\n", A, B, A | B)
end
 
@printf("\n%8s | %8s | %8s\n", "A", "B", "A ≡ B")
for (A, B) in Iterators.product(tril, tril)
@printf("%8s | %8s | %8s\n", A, B, A == B)
end
 
⊃(A, B) = B | !A
 
@printf("\n%8s | %8s | %8s\n", "A", "B", "A ⊃ B")
for (A, B) in Iterators.product(tril, tril)
@printf("%8s | %8s | %8s\n", A, B, A ⊃ B)
end</syntaxhighlight>
 
{{out}}
<pre> A | ¬A
true | false
missing | missing
false | true
 
A | B | A ∧ B
true | true | true
missing | true | missing
false | true | false
true | missing | missing
missing | missing | missing
false | missing | false
true | false | false
missing | false | false
false | false | false
 
A | B | A ∨ B
true | true | true
missing | true | true
false | true | true
true | missing | true
missing | missing | missing
false | missing | missing
true | false | true
missing | false | missing
false | false | false
 
A | B | A ≡ B
true | true | true
missing | true | missing
false | true | false
true | missing | missing
missing | missing | missing
false | missing | missing
true | false | false
missing | false | missing
false | false | true
 
A | B | A ⊃ B
true | true | true
missing | true | true
false | true | true
true | missing | missing
missing | missing | missing
false | missing | true
true | false | false
missing | false | missing</pre>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.2
 
enum class Trit {
Line 2,736 ⟶ 3,426:
println()
}
}</langsyntaxhighlight>
 
{{out}}
Line 2,770 ⟶ 3,460:
F | F M T
</pre>
 
=={{header|langur}}==
{{trans|Go}}
<syntaxhighlight lang="langur"># borrowing null for "maybe"
val .trSet = [false, null, true]
 
val .and = fn .a, .b: switch[and] .a, .b {
case true, null:
case null, true:
case null: null
default: .a and .b
}
 
val .or = fn .a, .b: switch[and] .a, .b {
case false, null:
case null, false:
case null: null
default: .a or .b
}
 
val .imply = fn .a, .b: if(.a nor .b: not? .a; .b)
 
# formatting function for the result values
# replacing null with "maybe"
# using left alignment of 5 code points
val .F = fn .r: "{{nn [.r, "maybe"]:-5}}"
 
writeln "a not a"
for .a in .trSet {
writeln "{{.a:fn F}} {{not? .a:fn F}}"
}
 
writeln "\na b a and b"
for .a in .trSet {
for .b in .trSet {
writeln "{{.a:fn F}} {{.b:fn F}} {{.and(.a, .b):fn F}}"
}
}
 
writeln "\na b a or b"
for .a in .trSet {
for .b in .trSet {
writeln "{{.a:fn F}} {{.b:fn F}} {{.or(.a, .b):fn F}}"
}
}
 
writeln "\na b a implies b"
for .a in .trSet {
for .b in .trSet {
writeln "{{.a:fn F}} {{.b:fn F}} {{.imply(.a, .b):fn F}}"
}
}
 
writeln "\na b a eq b"
for .a in .trSet {
for .b in .trSet {
writeln "{{.a:fn F}} {{.b:fn F}} {{.a ==? .b:fn F}}"
}
}
</syntaxhighlight>
 
{{out}}
<pre>a not a
false true
maybe maybe
true false
 
a b a and b
false false false
false maybe false
false true false
maybe false false
maybe maybe maybe
maybe true maybe
true false false
true maybe maybe
true true true
 
a b a or b
false false false
false maybe maybe
false true true
maybe false maybe
maybe maybe maybe
maybe true true
true false true
true maybe true
true true true
 
a b a implies b
false false true
false maybe true
false true true
maybe false maybe
maybe maybe maybe
maybe true true
true false false
true maybe maybe
true true true
 
a b a eq b
false false true
false maybe maybe
false true false
maybe false maybe
maybe maybe maybe
maybe true maybe
true false false
true maybe maybe
true true true </pre>
 
=={{header|Liberty BASIC}}==
<syntaxhighlight lang="lb">
<lang lb>
'ternary logic
'0 1 2
Line 2,843 ⟶ 3,643:
longName3$ = word$("False,Don't know,True", i+1, ",")
end function
</langsyntaxhighlight>
 
{{out}}
Line 2,869 ⟶ 3,669:
T ? ? T ? ?
T T T T T F
</pre>
 
=={{header|M2000 Interpreter}}==
 
<syntaxhighlight lang="m2000 interpreter">module Ternary_logic {
class trit {
private:
variant val
function copy() {
m=this
m.trit
=m
}
public:
enum ternary {
True="True"
Maybe="Maybe"
False="False"
}
function true() {
=.copy(.True)
}
function maybe() {
=.copy(.Maybe)
}
function false() {
=.copy(.False)
}
operator "==" (k as trit) {
push .val=k.val
}
operator "^^" (k as trit) {
select enum .val
case .True
.val<=k.val
case .False
.val<=.False
case else
if k.val=.False then .val<=.False else .val<=.Maybe
end select
}
operator "^|" (k as trit) {
select enum .val
case .True
.val<=k.val
case .False
.val<=.True
case else
if k.val=.True then .val<=.True else .val<=.Maybe
end select
}
operator "||" (k as trit) {
select enum .val
case .False
.val<=k.val
case .True
.val<=.True
case else
if k.val=.True then .val<=.True else .val<=.Maybe
end select
}
operator "~~" (k as trit) {
select enum .val
case .True
.val<=k.val
case .False
if k.val=.True then .val<=.False else.if k.val=.False then .val<=.True else .val<=k.val
case else
.val<=.Maybe
end select
}
operator unary {
select enum .val
case .True
.val<=.False
case .False
.val<=.True
end select
}
group value {
value {
link parent val to val
=val
}
}
module trit {
if empty or not isnum then
read s as .ternary=.Maybe
.val<=s
else.if isnum then
read what
if what then
.val<=.True
else
.val<=.False
end if
end if
}
}
function enum2array(t) {
m=each(t)
while m {data eval(m)}
=array([])
}
string out, nl={
}
q=trit()
m=trit()
k=enum2array(q.ternary)
out ="not a" + nl
a=each(k)
while a
q=trit(array(a))
z=-q
out +=" ternary_not "+(q.value) + " = " + (z.value) + nl
end while
out +="a and b" + nl
a=each(k)
while a
b=each(k)
while b
q=trit(array(a))
m=trit(array(b))
z=q ^^ m
out += " " + (q.value) + " ternary_and " + (m.value) + " = " + (z.value) + nl
end while
end while
out +="a or b" + nl
a=each(k)
while a
b=each(k)
while b
q=trit(array(a))
m=trit(array(b))
z=q || m
out += " " + (q.value) + " ternary_or " + (m.value) + " = " + (z.value) + nl
end while
end while
out +="if a then b" + nl
a=each(k)
while a
b=each(k)
while b
q=trit(array(a))
m=trit(array(b))
z=q ^| m
out += " if " + (q.value) + " then " + (m.value) + " = " + (z.value) + nl
end while
end while
out +="a is equivalent to b" + nl
a=each(k)
while a
b=each(k)
while b
q=trit(array(a))
m=trit(array(b))
z=q ~~ m
out += " "+(q.value) + " is equivalent to " + (m.value) + " = " + (z.value) + nl
end while
end while
report out
clipboard out
}
Ternary_logic
</syntaxhighlight>
{{out}}
<pre>not a
ternary_not True = False
ternary_not Maybe = Maybe
ternary_not False = True
a and b
True ternary_and True = True
True ternary_and Maybe = Maybe
True ternary_and False = False
Maybe ternary_and True = Maybe
Maybe ternary_and Maybe = Maybe
Maybe ternary_and False = False
False ternary_and True = False
False ternary_and Maybe = False
False ternary_and False = False
a or b
True ternary_or True = True
True ternary_or Maybe = True
True ternary_or False = True
Maybe ternary_or True = True
Maybe ternary_or Maybe = Maybe
Maybe ternary_or False = Maybe
False ternary_or True = True
False ternary_or Maybe = Maybe
False ternary_or False = False
if a then b
if True then True = True
if True then Maybe = Maybe
if True then False = False
if Maybe then True = True
if Maybe then Maybe = Maybe
if Maybe then False = Maybe
if False then True = True
if False then Maybe = True
if False then False = True
a is equivalent to b
True is equivalent to True = True
True is equivalent to Maybe = Maybe
True is equivalent to False = False
Maybe is equivalent to True = Maybe
Maybe is equivalent to Maybe = Maybe
Maybe is equivalent to False = Maybe
False is equivalent to True = False
False is equivalent to Maybe = Maybe
False is equivalent to False = True
</pre>
 
Line 2,876 ⟶ 3,886:
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'''.
 
<langsyntaxhighlight Maplelang="maple">tv := [true, false, FAIL];
NotTable := Array(1..3, i->not tv[i] );
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] );
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] );</langsyntaxhighlight>
 
{{Out}}
 
<langsyntaxhighlight Maplelang="maple">> tv := [true, false, FAIL];
tv := [true, false, FAIL]
 
Line 2,917 ⟶ 3,927:
ImpliesTable := [true true true]
[ ]
[true FAIL FAIL]</langsyntaxhighlight>
 
=={{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".
<langsyntaxhighlight lang="mathematica">Maybe /: ! Maybe = Maybe;
Maybe /: (And | Or | Nand | Nor | Xor | Xnor | Implies | Equivalent)[Maybe, Maybe] = Maybe;</langsyntaxhighlight>
Example:
<langsyntaxhighlight lang="mathematica">trits = {True, Maybe, False};
Print@Grid[
ArrayFlatten[{{{{Not}}, {{Null}}}, {List /@ trits,
Line 2,932 ⟶ 3,942:
Null}}}, {{{Null}}, {trits}}, {List /@ trits,
Outer[operator, trits, trits]}}]], {operator, {And, Or, Nand,
Nor, Xor, Xnor, Implies, Equivalent}}]</langsyntaxhighlight>
{{out}}
<pre>Not
Line 2,938 ⟶ 3,948:
Maybe Maybe
False True
 
 
 
And
Line 2,946 ⟶ 3,954:
Maybe Maybe Maybe False
False False False False
 
 
 
Line 2,954 ⟶ 3,961:
Maybe True Maybe Maybe
False True Maybe False
 
 
 
Line 2,962 ⟶ 3,968:
Maybe Maybe Maybe True
False True True True
 
 
 
Line 2,970 ⟶ 3,975:
Maybe False Maybe Maybe
False False Maybe True
 
 
 
Line 2,978 ⟶ 3,982:
Maybe Maybe Maybe Maybe
False True Maybe False
 
 
 
Line 2,994 ⟶ 3,997:
Maybe True Maybe Maybe
False True True True
 
 
 
Line 3,001 ⟶ 4,003:
True True Maybe False
Maybe Maybe Maybe Maybe
False False Maybe True</pre>
 
</pre>
 
=={{header|МК-61/52}}==
<syntaxhighlight lang="text">П0 Сx С/П ^ 1 + 3 * + 1
+ 3 x^y ИП0 <-> / [x] ^ ^ 3
/ [x] 3 * - 1 - С/П 1 5
6 3 3 БП 00 1 9 5 6 9
БП 00 1 5 9 2 9 БП 00 1
5 6 6 5 БП 00 /-/ ЗН С/П</langsyntaxhighlight>
 
<u>Instruction</u>:
Line 3,022 ⟶ 4,022:
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">type Trit* = enum ttrue, tmaybe, tfalse
 
proc `$`*(a: Trit): string =
Line 3,064 ⟶ 4,064:
t[a][b]
 
import strutils
 
when isMainModule:
var
 
op1 = ttrue
import strutils
op2 = ttrue
 
for t in Trit:
echo "Not ", t , ": ", not t
 
for op1 in Trit:
for op2 in Trit:
echo "$# and $#: $#".format(op1, op2, op1 and op2)
echo "$# or $#: $#".format(op1, op2, op1 or op2)
echo "$# then $#: $#".format(op1, op2, op1.then op2)
echo "$# equiv $#: $#".format(op1, op2, op1.equiv op2)</langsyntaxhighlight>
{{out}}
<pre>Not T: F
Line 3,122 ⟶ 4,121:
=={{header|OCaml}}==
 
<langsyntaxhighlight lang="ocaml">type trit = True | False | Maybe
 
let t_not = function
Line 3,165 ⟶ 4,164:
print t_imply "Then";
print t_eq "Equiv";
;;</langsyntaxhighlight>
 
{{out}}
Line 3,215 ⟶ 4,214:
=== 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:
<langsyntaxhighlight OCamllang="ocaml">type trit = True | False | Maybe
 
let to_bin = function True -> [true] | False -> [false] | Maybe -> [true;false]
Line 3,254 ⟶ 4,253:
table2 "or" t_or;;
table2 "equiv" t_equiv;;
table2 "implies" t_imply;;</langsyntaxhighlight>
{{out}}
<pre>
Line 3,307 ⟶ 4,306:
 
=={{header|ooRexx}}==
<syntaxhighlight lang="oorexx">
<lang ooRexx>
tritValues = .array~of(.trit~true, .trit~false, .trit~maybe)
tab = '09'x
Line 3,432 ⟶ 4,431:
else if self == .trit~maybe then return .trit~maybe
else return \other
</syntaxhighlight>
</lang>
 
<pre>
Line 3,486 ⟶ 4,485:
 
=={{header|Pascal}}==
<langsyntaxhighlight lang="pascal">Program TernaryLogic (output);
 
type
Line 3,576 ⟶ 4,575:
writeln('False ', terToStr(terEquals(terTrue,terFalse)), ' ', terToStr(terEquals(terMayBe,terFalse)), ' ', terToStr(terEquals(terFalse,terFalse)));
writeln;
end.</langsyntaxhighlight>
{{out}}
<pre>
Line 3,608 ⟶ 4,607:
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">use v5.36;
File <TT>Trit.pm</TT>:
<lang perl>package Trit;
 
package Trit;
# -1 = false ; 0 = maybe ; 1 = true
use List::Util qw(min max);
 
our @ISA = qw(Exporter);
use Exporter 'import';
our @EXPORT = qw(%E);
 
my %E = (true => 1, false => -1, maybe => 0);
our @EXPORT_OK = qw(TRUE FALSE MAYBE is_true is_false is_maybe);
our %EXPORT_TAGS = (
all => \@EXPORT_OK,
const => [qw(TRUE FALSE MAYBE)],
bool => [qw(is_true is_false is_maybe)],
);
 
use List::Util qw(min max);
 
use overload
'<=>' => sub ($a,$b) { $_[0]a->clonecmp($b) },
'<=>cmp' => sub ($a,$b) { $_[0]a->cmp($_[1]b) },
'cmp==' => sub ($a,$b,$) { $_[0]->cmp($_[1])a == $$b },
'==eq' => sub { (${a,$_[0]}b,$) == ${ $a->equiv($_[1]}b) },
'eq>' => sub ($a,$b,$) { $_[0]-$a >equiv( $_[1])E{$b} },
'><' => sub ($a,$b,$) { ${$_[0]}a < > $E{$_[1]b} },
'<>=' => sub ($a,$b,$) { ${$_[0]}a <>= ${$_[1]}b },
'><=' => sub ($a,$b,$) { ${$_[0]}a ><= ${$_[1]}b },
'<=|' => sub { (${a,$_[0]}b,$,$,$) <={ ${a->or($_[1]}b) },
'|&' => sub ($a,$b,$,$,$) { $_[0]a->orand($_[1]b) },
'&!' => sub ($a,$,$) { $_[0]a->andnot($_[1]) },
'!~' => sub ($a,$,$,$,$) { $_[0]a->not() },
'~neg' => sub ($a,$,$) { $_[0]->not()$$a },
'""' => sub ($a,$,$) { $_[0]a->tostr() },
'0+' => sub ($a,$,$) { $_[0]a->tonum() },
;
 
sub neweqv ($a,$b) {
$$a == $E{maybe} || $E{$b} == $E{maybe} ? $E{maybe} : # either arg 'maybe', return 'maybe'
{
$$a == $E{false} && $E{$b} == $E{false} ? $E{true} : # both args 'false', return 'true'
my ($class, $v) = @_;
min $$a, $E{$b} # either arg 'false', return 'false', otherwise 'true'
my $ret =
!defined($v) ? 0 :
$v eq 'true' ? 1 :
$v eq 'false'? -1 :
$v eq 'maybe'? 0 :
$v > 0 ? 1 :
$v < 0 ? -1 :
0;
return bless \$ret, $class;
}
 
# do tests in a manner that avoids overloaded operators
sub TRUE() { new Trit( 1) }
sub FALSE() { new Trit(-1$class, $v) }{
my $value =
sub MAYBE() { new Trit( 0) }
! defined $v ? $E{maybe} :
 
$v =~ /true/ ? $E{true} :
sub clone
$v =~ /false/ ? $E{false} :
{
my $retv =~ /maybe/ ? $E{$_[0]maybe}; :
$v gt $E{maybe} ? $E{true} :
return bless \$ret, ref($_[0]);
$v lt $E{maybe} ? $E{false} :
$E{maybe} ;
bless \$value, $class;
}
 
sub tostr ($a) { ${$_[0]}a > 0$E{maybe} ? "'true"' : ${$_[0]}a < 0$E{maybe} ? "'false"' : "'maybe"' }
sub tonum ($a) { ${$_[0]}a }
 
sub is_truenot { ($a) {$_[0]} Trit->new( -$a 0) }
sub is_falsecmp { ($a,$b) { Trit->new( $_[0]}a <=> $b 0) }
sub is_maybeand { ($a,$b) { Trit->new( min $_[0]}a, ==$b 0) }
sub or ($a,$b) { Trit->new( max $a, $b ) }
sub equiv ($a,$b) { Trit->new( eqv $a, $b ) }
 
package main;
sub cmp { ${$_[0]} <=> ${$_[1]} }
Trit->import;
sub not { new Trit(-${$_[0]}) }
sub and { new Trit(min(${$_[0]}, ${$_[1]}) ) }
sub or { new Trit(max(${$_[0]}, ${$_[1]}) ) }
 
submy equiv@a {= new( Trit->new( $E{$_[0]true}), * Trit->new($E{$_[1]maybe} ), }</langTrit->new($E{false}) );
printf "Codes for logic values: %6s = %d %6s = %d %6s = %d\n", @a[0, 0, 1, 1, 2, 2];
File <TT>test.pl</TT>:
<lang perl>use Trit ':all';
 
# prefix ! (not) ['~' also can be used]
my @a = (TRUE(), MAYBE(), FALSE());
say "\na\tNOT a";
print "$_\t".(!$_)."\n" for @a;
 
# infix & (and)
print "\na\tNOT a\n";
say "\nAND\t" . join("\t",@a);
print "$_\t".(!$_)."\n" for @a; # Example of use of prefix operator NOT. Tilde ~ also can be used.
for my $a (@a) { print $a; print "\t" . ($a & $_) for @a; say '' }
 
# infix | (or)
say "\nOR\t" . join("\t",@a);
for my $a (@a) { print $a; print "\t" . ($a | $_) for @a; say '' }
 
# infix eq (equivalence)
print "\nAND\t".join("\t",@a)."\n";
forsay my"\nEQV\t" $a. join("\t",@a) {;
for my $a (@a) { print $a; print "\t" . ($a eq $_) for @a; say '' }
print $a;
for my $b (@a) {
print "\t".($a & $b); # Example of use of infix & (and)
}
print "\n";
}
 
# infix == (equality)
print "\nOR\t".join("\t",@a)."\n";
forsay my"\n==\t" $a. join("\t",@a) {;
for my $a (@a) { print $a; print "\t" . ($a == $_) for @a; say '' }</syntaxhighlight>
print $a;
{{out}}
for my $b (@a) {
<pre>Codes for logic values: true = 1 maybe = 0 false = -1
print "\t".($a | $b); # Example of use of infix | (or)
}
print "\n";
}
 
a NOT a
print "\nEQV\t".join("\t",@a)."\n";
for my $a (@a) {
print $a;
for my $b (@a) {
print "\t".($a eq $b); # Example of use of infix eq (equivalence)
}
print "\n";
}
 
print "\n==\t".join("\t",@a)."\n";
for my $a (@a) {
print $a;
for my $b (@a) {
print "\t".($a == $b); # Example of use of infix == (equality)
}
print "\n";
}</lang>
{{out}}
<pre>a NOT a
true false
maybe maybe
Line 3,748 ⟶ 4,715:
maybe 1
false 1</pre>
=={{header|Perl 6}}==
{{Works with|rakudo|2018.03}}
 
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:
enum Trit <Foo Moo Too>;
 
sub prefix:<¬> (Trit $a) { Trit(1-($a-1)) }
 
sub infix:<∧> (Trit $a, Trit $b) is equiv(&infix:<*>) { $a min $b }
sub infix:<∨> (Trit $a, Trit $b) is equiv(&infix:<+>) { $a max $b }
 
sub infix:<⇒> (Trit $a, Trit $b) is equiv(&infix:<..>) { ¬$a max $b }
sub infix:<≡> (Trit $a, Trit $b) is equiv(&infix:<eq>) { Trit(1 + ($a-1) * ($b-1)) }
 
# Testing:
say '¬';
say "Too {¬Too}";
say "Moo {¬Moo}";
say "Foo {¬Foo}";
 
sub tbl (&op,$name) {
say '';
say "$name Too Moo Foo";
say " ╔═══════════";
say "Too║{op Too,Too} {op Too,Moo} {op Too,Foo}";
say "Moo║{op Moo,Too} {op Moo,Moo} {op Moo,Foo}";
say "Foo║{op Foo,Too} {op Foo,Moo} {op Foo,Foo}";
}
 
tbl(&infix:<∧>, '∧');
tbl(&infix:<∨>, '∨');
tbl(&infix:<⇒>, '⇒');
tbl(&infix:<≡>, '≡');
 
say '';
say 'Precedence tests should all print "Too":';
say ~(
Foo ∧ Too ∨ Too ≡ Too,
Foo ∧ (Too ∨ Too) ≡ Foo,
Too ∨ Too ∧ Foo ≡ Too,
(Too ∨ Too) ∧ Foo ≡ Foo,
 
¬Too ∧ Too ∨ Too ≡ Too,
¬Too ∧ (Too ∨ Too) ≡ ¬Too,
Too ∨ Too ∧ ¬Too ≡ Too,
(Too ∨ Too) ∧ ¬Too ≡ ¬Too,
Foo ∧ Too ∨ Foo ⇒ Foo ≡ Too,
Foo ∧ Too ∨ Too ⇒ Foo ≡ Foo,
);</lang>
 
{{out}}
<pre>¬
Too Foo
Moo Moo
Foo Too
 
∧ Too Moo Foo
╔═══════════
Too║Too Moo Foo
Moo║Moo Moo Foo
Foo║Foo Foo Foo
 
∨ Too Moo Foo
╔═══════════
Too║Too Too Too
Moo║Too Moo Moo
Foo║Too Moo Foo
 
⇒ Too Moo Foo
╔═══════════
Too║Too Moo Foo
Moo║Too Moo Moo
Foo║Too Too Too
 
≡ Too Moo Foo
╔═══════════
Too║Too Moo Foo
Moo║Moo Moo Moo
Foo║Foo Moo Too
 
Precedence tests should all print "Too":
Too Too Too Too Too Too Too Too Too Too</pre>
 
=={{header|Phix}}==
{{libheader|Phix/basics}}
<lang Phix>enum type ternary T, M, F end type
<!--<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>
function t_not(ternary a)
<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>
return F+1-a
end function
<span style="color: #008080;">function</span> <span style="color: #000000;">t_not</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ternary</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">return</span> <span style="color: #000000;">F</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">a</span>
function t_and(ternary a, ternary b)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
return iff(a=T and b=T?T:iff(a=F or b=F?F:M))
end function
<span style="color: #008080;">function</span> <span style="color: #000000;">t_and</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ternary</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ternary</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">T</span> <span style="color: #008080;">and</span> <span style="color: #000000;">b</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: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">F</span> <span style="color: #008080;">or</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">=</span><span style="color: #000000;">F</span><span style="color: #0000FF;">?</span><span style="color: #000000;">F</span><span style="color: #0000FF;">:</span><span style="color: #000000;">M</span><span style="color: #0000FF;">))</span>
function t_or(ternary a, ternary b)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
return iff(a=T or b=T?T:iff(a=F and b=F?F:M))
end function
<span style="color: #008080;">function</span> <span style="color: #000000;">t_or</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ternary</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ternary</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">T</span> <span style="color: #008080;">or</span> <span style="color: #000000;">b</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: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">F</span> <span style="color: #008080;">and</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">=</span><span style="color: #000000;">F</span><span style="color: #0000FF;">?</span><span style="color: #000000;">F</span><span style="color: #0000FF;">:</span><span style="color: #000000;">M</span><span style="color: #0000FF;">))</span>
function t_xor(ternary a, ternary b)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
return iff(a=M or b=M?M:iff(a=b?F:T))
end function
<span style="color: #008080;">function</span> <span style="color: #000000;">t_xor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ternary</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ternary</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">M</span> <span style="color: #008080;">or</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">=</span><span style="color: #000000;">M</span><span style="color: #0000FF;">?</span><span style="color: #000000;">M</span><span style="color: #0000FF;">:</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">b</span><span style="color: #0000FF;">?</span><span style="color: #000000;">F</span><span style="color: #0000FF;">:</span><span style="color: #000000;">T</span><span style="color: #0000FF;">))</span>
function t_implies(ternary a, ternary b)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
return iff(a=F or b=T?T:iff(a=T and b=F?F:M))
end function
<span style="color: #008080;">function</span> <span style="color: #000000;">t_implies</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ternary</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ternary</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">F</span> <span style="color: #008080;">or</span> <span style="color: #000000;">b</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: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">T</span> <span style="color: #008080;">and</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">=</span><span style="color: #000000;">F</span><span style="color: #0000FF;">?</span><span style="color: #000000;">F</span><span style="color: #0000FF;">:</span><span style="color: #000000;">M</span><span style="color: #0000FF;">))</span>
function t_equal(ternary a, ternary b)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
return iff(a=M or b=M?M:iff(a=b?T:F))
end function
<span style="color: #008080;">function</span> <span style="color: #000000;">t_equal</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ternary</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ternary</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">M</span> <span style="color: #008080;">or</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">=</span><span style="color: #000000;">M</span><span style="color: #0000FF;">?</span><span style="color: #000000;">M</span><span style="color: #0000FF;">:</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">b</span><span style="color: #0000FF;">?</span><span style="color: #000000;">T</span><span style="color: #0000FF;">:</span><span style="color: #000000;">F</span><span style="color: #0000FF;">))</span>
function t_string(ternary a)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
return iff(a=T?"T":iff(a=M?"?":"F"))
end function
<span style="color: #008080;">function</span> <span style="color: #000000;">t_string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ternary</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">T</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"T"</span><span style="color: #0000FF;">:</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">M</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"?"</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"F"</span><span style="color: #0000FF;">))</span>
procedure show_truth_table(integer rid, integer unary, string name)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
printf(1,"%-3s |%s\n",{name,iff(unary?"":" T | ? | F")})
printf(1,"----+---%s\n",{iff(unary?"":"+---+---")})
<span style="color: #008080;">procedure</span> <span style="color: #000000;">show_truth_table</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">unary</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">name</span><span style="color: #0000FF;">)</span>
for x=T to F do
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%-3s |%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">name</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">unary</span><span style="color: #0000FF;">?</span><span style="color: #008000;">""</span><span style="color: #0000FF;">:</span><span style="color: #008000;">" T | ? | F"</span><span style="color: #0000FF;">)})</span>
printf(1," %s ",{t_string(x)})
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"----+---%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">unary</span><span style="color: #0000FF;">?</span><span style="color: #008000;">""</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"+---+---"</span><span style="color: #0000FF;">)})</span>
if unary then
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">T</span> <span style="color: #008080;">to</span> <span style="color: #000000;">F</span> <span style="color: #008080;">do</span>
printf(1," | %s",{t_string(call_func(rid,{x}))})
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %s "</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">t_string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)})</span>
else
<span style="color: #008080;">if</span> <span style="color: #000000;">unary</span> <span style="color: #008080;">then</span>
for y=T to F do
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" | %s"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">t_string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rid</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">))})</span>
printf(1," | %s",{t_string(call_func(rid,{x,y}))})
<span style="color: end for#008080;">else</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">T</span> <span style="color: #008080;">to</span> <span style="color: #000000;">F</span> <span style="color: #008080;">do</span>
end if
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" | %s"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">t_string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rid</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">))})</span>
printf(1,"\n")
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
printf(1,"\n")
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
show_truth_table(routine_id("t_not"),1,"not")
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
show_truth_table(routine_id("t_and"),0,"and")
show_truth_table(routine_id("t_or"),0,"or")
<span style="color: #000000;">show_truth_table</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t_not</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"not"</span><span style="color: #0000FF;">)</span>
show_truth_table(routine_id("t_xor"),0,"xor")
<span style="color: #000000;">show_truth_table</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t_and</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"and"</span><span style="color: #0000FF;">)</span>
show_truth_table(routine_id("t_implies"),0,"imp")
<span style="color: #000000;">show_truth_table</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t_or</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"or"</span><span style="color: #0000FF;">)</span>
show_truth_table(routine_id("t_equal"),0,"eq")</lang>
<span style="color: #000000;">show_truth_table</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t_xor</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"xor"</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>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 3,929 ⟶ 4,815:
=={{header|PHP}}==
Save the sample code as executable shell script on your *nix system:
<langsyntaxhighlight PHPlang="php">#!/usr/bin/php
<?php
 
Line 3,991 ⟶ 4,877:
}
 
</syntaxhighlight>
</lang>
Sample output:
<pre>--- Sample output for a equivalent b ---
Line 4,005 ⟶ 4,891:
for a=false and b=false a equivalent b is true
</pre>
 
=={{header|Picat}}==
<syntaxhighlight lang="picat">main =>
(show_op1('!') ; true),
nl,
foreach(Op in ['/\\','\\/','->','=='])
(show_op2(Op) ; nl,true)
end.
 
ternary(true,'!') = false.
ternary(maybe,'!') = maybe.
ternary(false,'!') = true.
 
ternary(Cond,'!') = Res =>
C1 = cond(Cond == maybe,maybe,cond(Cond,true,false)),
Res = ternary(C1,'!').
 
ternary(true,'/\\',A) = A.
ternary(maybe,'/\\',A) = cond(A==false,false,maybe).
ternary(false,'/\\',_A) = false.
 
ternary(true,'\\/',_A) = true.
ternary(maybe,'\\/',A) = cond(A==true,true, maybe).
ternary(false,'\\/',A) = A.
 
ternary(true,'->',A) = A.
ternary(maybe,'->',A) = cond(A==true,true,maybe).
ternary(false,'->',_) = true.
 
ternary(true,'==',A) = A.
ternary(maybe,'==',_) = maybe.
ternary(false,'==',A) = ternary(A,'!').
 
ternary(Cond1,Op,Cond2) = Res =>
C1 = cond(Cond1 == maybe,maybe,cond(Cond1,true,false)),
C2 = cond(Cond2 == maybe,maybe,cond(Cond2,true,false)),
Res = ternary(C1,Op,C2).
 
show_op1(Op) =>
println(Op),
println(['_' : _ in 1..11]),
foreach(V1 in [true,maybe,false])
V2 = ternary(V1,Op),
printf("%5w %5w \n",V1,V2)
end,
nl.
 
show_op2(Op) =>
Vs = [true,maybe,false],
printf("%2w %5w %5w %5w\n",Op,Vs[1],Vs[2],Vs[3]),
println(['_' : _ in 1..25]),
foreach(V1 in Vs)
printf("%-5w | ", V1),
foreach(V2 in Vs)
C = ternary(V1,Op,V2),
printf("%5w ",C)
end,
nl
end,
nl.</syntaxhighlight>
 
{{out}}
<pre>!
___________
true false
maybe maybe
false true
 
 
/\ true maybe false
_________________________
true | true maybe false
maybe | maybe maybe false
false | false false false
 
\/ true maybe false
_________________________
true | true true true
maybe | true maybe maybe
false | true maybe false
 
-> true maybe false
_________________________
true | true maybe false
maybe | true maybe maybe
false | true true true
 
== true maybe false
_________________________
true | true maybe false
maybe | maybe maybe maybe
false | false maybe true </pre>
 
===Simple examples===
<syntaxhighlight lang="picat">main =>
println(ternary(10 > 3,'->',maybe).ternary('!')),
println(ternary(4 < 18,'/\\',$not membchk('a',"picat")).ternary('->',maybe).ternary('==',true)).</syntaxhighlight>
 
{{out}}
<pre>maybe
true</pre>
 
=={{header|PicoLisp}}==
In addition for the standard T (for "true") and NIL (for "false") we define 0 (zero, for "maybe").
<langsyntaxhighlight PicoLisplang="picolisp">(de 3not (A)
(or (=0 A) (not A)) )
 
Line 4,032 ⟶ 5,019:
((=T A) B)
((=0 A) 0)
(T (3not B)) ) )</langsyntaxhighlight>
Test:
<langsyntaxhighlight PicoLisplang="picolisp">(for X '(T 0 NIL)
(println 'not X '-> (3not X)) )
 
Line 4,040 ⟶ 5,027:
(for X '(T 0 NIL)
(for Y '(T 0 NIL)
(println X (car Fun) Y '-> ((cdr Fun) X Y)) ) ) )</langsyntaxhighlight>
{{out}}
<pre style="height:20em;overflow:scroll">not T -> NIL
not 0 -> 0
not NIL -> T
Line 4,081 ⟶ 5,068:
NIL equivalent 0 -> 0
NIL equivalent NIL -> T</pre>
 
=={{header|PureBasic}}==
{{trans|FreeBasic}}
<syntaxhighlight lang="purebasic">DataSection
TLogic:
Data.i -1,0,1
TSymb:
Data.s "F","?","T"
EndDataSection
 
Structure TL
F.i
M.i
T.i
EndStructure
 
Structure SYM
TS.s{2}[3]
EndStructure
 
*L.TL=?TLogic
*S.SYM=?TSymb
 
Procedure.i NOT3(*x.TL)
ProcedureReturn -*x
EndProcedure
 
Procedure.i AND3(*x.TL,*y.TL)
If *x>*y : ProcedureReturn *y : Else : ProcedureReturn *x : EndIf
EndProcedure
 
Procedure.i OR3(*x.TL,*y.TL)
If *x<*y : ProcedureReturn *y : Else : ProcedureReturn *x : EndIf
EndProcedure
 
Procedure.i EQV3(*x.TL,*y.TL)
ProcedureReturn *x * *y
EndProcedure
 
Procedure.i IMP3(*x.TL,*y.TL)
If -*y>*x : ProcedureReturn -*y : Else : ProcedureReturn *x : EndIf
EndProcedure
 
If OpenConsole("")
PrintN(" (AND) ( OR) (EQV) (IMP) (NOT)")
PrintN(" F ? T F ? T F ? T F ? T ")
PrintN(" -------------------------------------------------")
For *i.TL=*L\F To *L\T
rs$=" "+*S\TS[*i+1]+" | "
rs$+*S\TS[AND3(*L\F,*i)+1]+" "+*S\TS[AND3(*L\M,*i)+1]+" "+*S\TS[AND3(*L\T,*i)+1]
rs$+" "
rs$+*S\TS[OR3(*L\F,*i)+1] +" "+*S\TS[OR3(*L\M,*i)+1] +" "+*S\TS[OR3(*L\T,*i)+1]
rs$+" "
rs$+*S\TS[EQV3(*L\F,*i)+1]+" "+*S\TS[EQV3(*L\M,*i)+1]+" "+*S\TS[EQV3(*L\T,*i)+1]
rs$+" "
rs$+*S\TS[IMP3(*L\F,*i)+1]+" "+*S\TS[IMP3(*L\M,*i)+1]+" "+*S\TS[IMP3(*L\T,*i)+1]
rs$+" "+*S\TS[NOT3(*i)+1]
PrintN(rs$)
Next
EndIf
Input()</syntaxhighlight>
{{out}}
<pre> (AND) ( OR) (EQV) (IMP) (NOT)
F ? T F ? T F ? T F ? T
-------------------------------------------------
F | F F F F ? T T ? F T T T T
? | F ? ? ? ? T ? ? ? ? ? T ?
T | F ? T T T T F ? T F ? T F
</pre>
 
=={{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.
<langsyntaxhighlight lang="python">class Trit(int):
def __new__(cls, value):
if value == 'TRUE':
Line 4,212 ⟶ 5,268:
for b in values:
expr = '%s %s %s' % (a, op, b)
print(' %s = %s' % (expr, eval(expr)))</langsyntaxhighlight>
 
{{out}}
Line 4,262 ⟶ 5,318:
>>> </pre>
 
=={{header|Quackery}}==
<syntaxhighlight lang="quackery ">
[ 2 ] is maybe ( --> t )
[ table 2 0 1 ] is jiggle ( t --> n )
[ jiggle 1+ ]this[ swap peek do ]done[ ] is 1-trit ( t --> t )
[ swap jiggle 1+ ]this[
swap peek
swap jiggle peek do ]done[ ] is 2-trits ( t t --> t )
[ 1-trit $ "true" $ "maybe" $ "false" ] is trit$ ( t --> $ )
[ trit$ echo$ ] is echotrit ( t --> )
[ dup echotrit true = if sp ] is paddedtrit ( t --> )
( true maybe false )
[ 1-trit false maybe true ] is t.not ( t --> t )
( true maybe false )
[ 2-trits ( true ) [ false maybe true ]
( maybe ) [ maybe maybe true ]
( false ) [ true true true ] ] is t.nand ( t t --> t )
( true maybe false )
[ 2-trits ( true ) [ true maybe false ]
( maybe ) [ maybe maybe false ]
( false ) [ false false false ] ] is t.and ( t t --> t )
( true maybe false )
[ 2-trits ( true ) [ true true true ]
( maybe ) [ true maybe maybe ]
( false ) [ true maybe false ] ] is t.or ( t t --> t )
( true maybe false )
[ 2-trits ( true ) [ false maybe true ]
( maybe ) [ maybe maybe maybe ]
( false ) [ true maybe false ] ] is t.xor ( t t --> t )
( Quackery does not have operators for material implication
(if a then b, a implies b) or material equivalence
(a ≣ b, A <=> b). However, The Book of Quackery notes that they
can be defined as:
"[ swap not or ] is implies ( a b --> c )"
"[ xor not ] is <=> ( a b --> c )"
so we will adapt these to test some of the ternary operators. )
[ swap t.not t.or ] is t.implies ( t t --> t )
[ t.xor t.not ] is t.<=> ( t t --> t )
cr
say " t.not | true | maybe | false" cr
say " ---------------------------------" cr
say " | " true t.not paddedtrit sp
say "| " maybe t.not paddedtrit sp
say "| " false t.not paddedtrit cr
cr
say " t.and | true | maybe | false" cr
say " ---------------------------------" cr
say " true | " true true t.and paddedtrit sp
say "| " true maybe t.and paddedtrit sp
say "| " true false t.and paddedtrit cr
say " maybe | " maybe true t.and paddedtrit sp
say "| " maybe maybe t.and paddedtrit sp
say "| " maybe false t.and paddedtrit cr
say " false | " false true t.and paddedtrit sp
say "| " false maybe t.and paddedtrit sp
say "| " false false t.and paddedtrit cr
cr
say " t.or | true | maybe | false" cr
say " ---------------------------------" cr
say " true | " true true t.or paddedtrit sp
say "| " true maybe t.or paddedtrit sp
say "| " true false t.or paddedtrit cr
say " maybe | " maybe true t.or paddedtrit sp
say "| " maybe maybe t.or paddedtrit sp
say "| " maybe false t.or paddedtrit cr
say " false | " false true t.or paddedtrit sp
say "| " false maybe t.or paddedtrit sp
say "| " false false t.or paddedtrit cr
cr
say " t.implies | true | maybe | false" cr
say " ---------------------------------" cr
say " true | " true true t.implies paddedtrit sp
say "| " true maybe t.implies paddedtrit sp
say "| " true false t.implies paddedtrit cr
say " maybe | " maybe true t.implies paddedtrit sp
say "| " maybe maybe t.implies paddedtrit sp
say "| " maybe false t.implies paddedtrit cr
say " false | " false true t.implies paddedtrit sp
say "| " false maybe t.implies paddedtrit sp
say "| " false false t.implies paddedtrit cr
cr
say " t.<=> | true | maybe | false" cr
say " ---------------------------------" cr
say " true | " true true t.<=> paddedtrit sp
say "| " true maybe t.<=> paddedtrit sp
say "| " true false t.<=> paddedtrit cr
say " maybe | " maybe true t.<=> paddedtrit sp
say "| " maybe maybe t.<=> paddedtrit sp
say "| " maybe false t.<=> paddedtrit cr
say " false | " false true t.<=> paddedtrit sp
say "| " false maybe t.<=> paddedtrit sp
say "| " false false t.<=> paddedtrit cr</syntaxhighlight>
 
'''Output:'''
<pre> t.not | true | maybe | false
---------------------------------
| false | maybe | true
 
t.and | true | maybe | false
---------------------------------
true | true | maybe | false
maybe | maybe | maybe | false
false | false | false | false
 
t.or | true | maybe | false
---------------------------------
true | true | true | true
maybe | true | maybe | maybe
false | true | maybe | false
 
t.implies | true | maybe | false
---------------------------------
true | true | maybe | false
maybe | true | maybe | maybe
false | true | true | true
 
t.<=> | true | maybe | false
---------------------------------
true | true | maybe | false
maybe | maybe | maybe | maybe
false | false | maybe | true
</pre>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">#lang typed/racket
 
; to avoid the hassle of adding a maybe value that is as special as
Line 4,325 ⟶ 5,519:
(for*: : Void ([a (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))))</langsyntaxhighlight>
 
{{out}}
Line 4,367 ⟶ 5,561:
false iff maybe = maybe
false iff false = true
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{Works with|rakudo|2018.03}}
 
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).
 
<syntaxhighlight lang="raku" line># Implementation:
enum Trit <Foo Moo Too>;
 
sub prefix:<¬> (Trit $a) { Trit(1-($a-1)) }
 
sub infix:<∧> (Trit $a, Trit $b) is equiv(&infix:<*>) { $a min $b }
sub infix:<∨> (Trit $a, Trit $b) is equiv(&infix:<+>) { $a max $b }
 
sub infix:<⇒> (Trit $a, Trit $b) is equiv(&infix:<..>) { ¬$a max $b }
sub infix:<≡> (Trit $a, Trit $b) is equiv(&infix:<eq>) { Trit(1 + ($a-1) * ($b-1)) }
 
# Testing:
say '¬';
say "Too {¬Too}";
say "Moo {¬Moo}";
say "Foo {¬Foo}";
 
sub tbl (&op,$name) {
say '';
say "$name Too Moo Foo";
say " ╔═══════════";
say "Too║{op Too,Too} {op Too,Moo} {op Too,Foo}";
say "Moo║{op Moo,Too} {op Moo,Moo} {op Moo,Foo}";
say "Foo║{op Foo,Too} {op Foo,Moo} {op Foo,Foo}";
}
 
tbl(&infix:<∧>, '∧');
tbl(&infix:<∨>, '∨');
tbl(&infix:<⇒>, '⇒');
tbl(&infix:<≡>, '≡');
 
say '';
say 'Precedence tests should all print "Too":';
say ~(
Foo ∧ Too ∨ Too ≡ Too,
Foo ∧ (Too ∨ Too) ≡ Foo,
Too ∨ Too ∧ Foo ≡ Too,
(Too ∨ Too) ∧ Foo ≡ Foo,
 
¬Too ∧ Too ∨ Too ≡ Too,
¬Too ∧ (Too ∨ Too) ≡ ¬Too,
Too ∨ Too ∧ ¬Too ≡ Too,
(Too ∨ Too) ∧ ¬Too ≡ ¬Too,
Foo ∧ Too ∨ Foo ⇒ Foo ≡ Too,
Foo ∧ Too ∨ Too ⇒ Foo ≡ Foo,
);</syntaxhighlight>
 
{{out}}
<pre>¬
Too Foo
Moo Moo
Foo Too
 
∧ Too Moo Foo
╔═══════════
Too║Too Moo Foo
Moo║Moo Moo Foo
Foo║Foo Foo Foo
 
∨ Too Moo Foo
╔═══════════
Too║Too Too Too
Moo║Too Moo Moo
Foo║Too Moo Foo
 
⇒ Too Moo Foo
╔═══════════
Too║Too Moo Foo
Moo║Too Moo Moo
Foo║Too Too Too
 
≡ Too Moo Foo
╔═══════════
Too║Too Moo Foo
Moo║Moo Moo Moo
Foo║Foo Moo Too
 
Precedence tests should all print "Too":
Too Too Too Too Too Too Too Too Too Too</pre>
 
=={{header|Red}}==
{{Works with|Red|0.6.4}}
 
<syntaxhighlight lang="red">Red ["Ternary logic"]
 
; define trits as a set of 3 Red words: 'oui, 'non and 'bof
; ('bof is a French teenager word expressing indifference)
trits: [oui bof non]
 
; set the value of each word to itself
; so the expression " oui " will evaluate to word 'oui
foreach t trits [set t to-lit-word t]
 
; utility function to test if a word is a trit
trit?: function [t] [not none? find trits t]
 
; ------ prefix operators ------
; unary operator
tnot: !: function [a][
select [oui non oui bof bof] a
]
; binary (prefix) operators
tand: function [a b][
either all [a = oui b = oui][oui][
either any [a = non b = non][non][bof]
]]
tor: function [a b][
either any [a = oui b = oui][oui][
either all [a = non b = non][non][bof]
]]
timp: function [a b][
either a = oui [b][
either a = non [oui][
either b = oui [oui][bof]
]]]
teq: function [a b][
either any [a = bof b = bof][bof][
either a = b [oui][non]
]]
; ------ infix operators ------
&: make op! :tand
|: make op! :tor
=>: make op! :timp
<=>: make op! :teq
 
; some examples
probe init: [
a: oui
b: bof
c: non]
do init
foreach s [[! (! a)] [a & b] [a | (b & (oui | non))]
[! ((a | b) | b & c)] [(a & b) | c]][
print rejoin [pad mold s 25 " " do s]
]
</syntaxhighlight>
 
{{out}}
<pre>[
a: oui
b: bof
c: non
]
[! (! a)] oui
[a & b] bof
[a | (b & (oui | non))] oui
[! ((a | b) | b & c)] oui
[(a & b) | c] bof
</pre>
 
=={{header|REXX}}==
This REXX program is a re-worked version of the REXX program used for the Rosetta Code task: &nbsp; ''truth table''.
<langsyntaxhighlight lang="rexx">/*REXX program displays a ternary truth table [true, false, maybe] for the variables */
/*──── and one or more expressions. */
/*──── Infix notation is supported with one character propositional constants. */
Line 4,514 ⟶ 5,865:
/*──────────────────────────────────────────────────────────────────────────────────────*/
scan: procedure; parse arg x,at; L=length(x); t=L; lp=0; apost=0; quote=0
if at<0 then do; t=1; x= translate(x, '()', ")("); end
 
do j=abs(at) to t by sign(at); _=substr(x,j,1); __=substr(x,j,2)
Line 4,525 ⟶ 5,876:
apost=0; iterate
end
if _=='"' then do; quote=1; iterate; end
if _=="'" then do; apost=1; iterate; end
if _==' ' then iterate
if _=='(' then do; lp=lp+1; iterate; end
if lp\==0 then do; if _==')' then lp=lp-1; iterate; end
if datatype(_,'U') then return j - (at<0)
if at<0 then return j + 1
Line 4,535 ⟶ 5,886:
return min(j,L)
/*──────────────────────────────────────────────────────────────────────────────────────*/
changeFunc: procedure; parse arg z,fC,newF; funcPos= 0
do forever
funcPos= pos(fC, z, funcPos + 1); if funcPos==0 then return z
origPos= funcPos
z= changestr(fC, z, ",'"newF"',")
funcPos= funcPos + length(newF) + 4
where= scan(z, funcPos) ; z= insert( '}', z, where)
where= scan(z, 1 - origPos) ; z= insert('trit{', z, where)
end /*forever*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
trit: procedure; arg a,$,b; v= \(a==2 | b==2); o= (a==1 | b==1); z= (a==0 | b==0)
select
when $=='FALSE' then return 0
when $=='AND' then if v then return a & b; else return 2
when $=='NAIMPB' then if v then return \(\a & \b); else return 2
when $=='BOOLB' then return b
when $=='NBIMPA' then if v then return \(\b & \a); else return 2
when $=='BOOLA' then return a
when $=='XOR' then if v then return a && b ; else return 2
when $=='OR' then if v then return a | b ; else if o then return 1
else return 2
when $=='NOR' then if v then return \(a | b) ; else return 2
when $=='XNOR' then if v then return \(a && b) ; else return 2
when $=='NOTB' then if v then return \b ; else return 2
when $=='NOTA' then if v then return \a ; else return 2
when $=='AIMPB' then if v then return \(a & \b) ; else return 2
when $=='NAND' then if v then return \(a & b) ; else if z then return 1
else return 2
when $=='TRUE' then return 1
otherwise return -13 /*error, unknown function.*/
end /*select*/</lang>
</syntaxhighlight>
Some older REXXes don't have a &nbsp; '''changestr''' &nbsp; BIF, so one is included here &nbsp; ──► &nbsp; [[CHANGESTR.REX]].
<br><br>
Line 4,642 ⟶ 5,994:
maybe maybe ────► maybe
</pre>
 
=={{header|RPL}}==
Ternary logic can be considered as a simplified version of Zadeh's fuzzy logic. In this paradigm, boolean values turn into floating-point ones going from 0 (completely false) to 1 (completely true):
AND(a,b), OR(a,b) and NOT(a) are resp. redefined as MIN(a,b), MAX(a,b) and (1-a). Other boolean operators can then be built by combining these 3 atoms. A specific word is also needed to display results as ternary constants instead of numbers.
{{works with|Halcyon Calc|4.2.7}}
≪ 2 * CEIL 1 + { ‘FALSE’ ‘MAYBE’ ‘TRUE’ } SWAP GET ≫ ''''TELL'''’ STO
≪ OR EVAL '''TELL''' ≫ ''''TAND'''’ STO
≪ AND EVAL '''TELL''' ≫ ''''TOR'''’ STO
≪ 1 SWAP - EVAL '''TELL''' ≫ ''''TNOT'''’ STO
≪ SWAP '''TNOT TOR''' EVAL '''TELL''' ≫ ''''TIMPLY'''’ STO
≪ DUP2 '''TNOT TAND''' ROT '''TNOT''' ROT '''TAND TOR''' EVAL '''TELL''' ≫ ''''TXOR'''’ STO
1 ''''TRUE'''' STO 0.5 ''''MAYBE'''' STO 0 ''''FALSE'''' STO
 
FALSE MAYBE '''TXOR'''
1: ‘TRUE’
Only the Soviets could understand such a logic...
 
=={{header|Ruby}}==
Line 4,649 ⟶ 6,017:
 
{{works with|Ruby|1.9}}
<langsyntaxhighlight lang="ruby"># trit.rb - ternary logic
# http://rosettacode.org/wiki/Ternary_logic
 
Line 4,733 ⟶ 6,101:
# false.trit == obj # => false, maybe or true
def trit; TritMagic; end
end</langsyntaxhighlight>
 
This IRB session shows ternary not, and, or, equal.
 
<langsyntaxhighlight lang="ruby">$ irb
irb(main):001:0> require './trit'
=> true
Line 4,753 ⟶ 6,121:
=> false
irb(main):008:0> false.trit == maybe
=> maybe</langsyntaxhighlight>
 
This program shows all 9 outcomes from <code>a.trit ^ b</code>.
 
<langsyntaxhighlight lang="ruby">require 'trit'
maybe = MAYBE
 
Line 4,764 ⟶ 6,132:
printf "%5s ^ %5s => %5s\n", a, b, a.trit ^ b
end
end</langsyntaxhighlight>
 
<pre>$ ruby -I. trit-xor.rb
Line 4,778 ⟶ 6,146:
 
=={{header|Run BASIC}}==
<langsyntaxhighlight lang="runbasic">testFalse = 0 ' F
testDoNotKnow = 1 ' ?
testTrue = 2 ' T
Line 4,835 ⟶ 6,203:
function longName3$(i)
longName3$ = word$("False,Don't know,True", i+1, ",")
end function</langsyntaxhighlight><pre>Short and long names for ternary logic values
F False
? Don't know
Line 4,849 ⟶ 6,217:
<table border=1><TR align=center bgcolor=wheat><TD>x</td><td>y</td><td>x AND y</td><td>x OR y</td><td>x EQ y</td><td>x XOR y</td></tr><TR align=center><td>F</td><td>F</td><td>F</td><td>F</td><td>T</td><td>F</td></tr><TR align=center><td>F</td><td>?</td><td>F</td><td>?</td><td>F</td><td>T</td></tr><TR align=center><td>F</td><td>T</td><td>F</td><td>T</td><td>F</td><td>T</td></tr><TR align=center><td>?</td><td>F</td><td>F</td><td>?</td><td>F</td><td>T</td></tr><TR align=center><td>?</td><td>?</td><td>?</td><td>?</td><td>T</td><td>F</td></tr><TR align=center><td>?</td><td>T</td><td>?</td><td>T</td><td>F</td><td>T</td></tr><TR align=center><td>T</td><td>F</td><td>F</td><td>T</td><td>F</td><td>T</td></tr><TR align=center><td>T</td><td>?</td><td>?</td><td>T</td><td>F</td><td>T</td></tr><TR align=center><td>T</td><td>T</td><td>T</td><td>T</td><td>T</td><td>F</td></tr></table>
 
=={{Headerheader|ScalaRust}}==
{{trans|Kotlin}}
<lang scala>sealed trait Trit { self =>
<syntaxhighlight lang="rust">use std::{ops, fmt};
 
#[derive(Copy, Clone, Debug)]
enum Trit {
True,
Maybe,
False,
}
 
impl ops::Not for Trit {
type Output = Self;
fn not(self) -> Self {
match self {
Trit::True => Trit::False,
Trit::Maybe => Trit::Maybe,
Trit::False => Trit::True,
}
}
}
 
impl ops::BitAnd for Trit {
type Output = Self;
fn bitand(self, other: Self) -> Self {
match (self, other) {
(Trit::True, Trit::True) => Trit::True,
(Trit::False, _) | (_, Trit::False) => Trit::False,
_ => Trit::Maybe,
}
}
}
 
impl ops::BitOr for Trit {
type Output = Self;
fn bitor(self, other: Self) -> Self {
match (self, other) {
(Trit::True, _) | (_, Trit::True) => Trit::True,
(Trit::False, Trit::False) => Trit::False,
_ => Trit::Maybe,
}
}
}
 
impl Trit {
fn imp(self, other: Self) -> Self {
match self {
Trit::True => other,
Trit::Maybe => {
if let Trit::True = other {
Trit::True
} else {
Trit::Maybe
}
}
Trit::False => Trit::True,
}
}
 
fn eqv(self, other: Self) -> Self {
match self {
Trit::True => other,
Trit::Maybe => Trit::Maybe,
Trit::False => !other,
}
}
}
 
impl fmt::Display for Trit {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}",
match self {
Trit::True => 'T',
Trit::Maybe => 'M',
Trit::False => 'F',
}
)
}
}
 
static TRITS: [Trit; 3] = [Trit::True, Trit::Maybe, Trit::False];
 
fn main() {
println!("not");
println!("-------");
for &t in &TRITS {
println!(" {} | {}", t, !t);
}
table("and", |a, b| a & b);
table("or", |a, b| a | b);
table("imp", |a, b| a.imp(b));
table("eqv", |a, b| a.eqv(b));
}
 
fn table(title: &str, f: impl Fn(Trit, Trit) -> Trit) {
println!();
println!("{:3} | T M F", title);
println!("-------------");
for &t1 in &TRITS {
print!(" {} | ", t1);
for &t2 in &TRITS {
print!("{} ", f(t1, t2));
}
println!();
}
}</syntaxhighlight>
 
{{out}}
<pre>not
-------
T | F
M | M
F | T
 
and | T M F
-------------
T | T M F
M | M M F
F | F F F
 
or | T M F
-------------
T | T T T
M | T M M
F | T M F
 
imp | T M F
-------------
T | T M F
M | T M M
F | T T T
 
eqv | T M F
-------------
T | T M F
M | M M M
F | F M T </pre>
 
=={{header|Scala}}==
<syntaxhighlight lang="scala">sealed trait Trit { self =>
def nand(that:Trit):Trit=(this,that) match {
case (TFalse, _) => TTrue
Line 4,882 ⟶ 6,391:
println("\n- Equiv -")
for(a<-v; b<-v) println("%6s : %6s => %6s".format(a, b, a equiv b))
}</langsyntaxhighlight>
{{out}}
<pre>- NOT -
Line 4,952 ⟶ 6,461:
which use also short circuit evaluation.
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const type: trit is new enum
Line 5,019 ⟶ 6,528:
end func;
 
$ syntax expr: .().xor.() is -> 15;
const func trit: (in trit: aTrit1) xor (in trit: aTrit2) is
return tritImplies[succ(ord(aTrit1))][succ(ord(aTrit2))];
Line 5,026 ⟶ 6,535:
return tritImplies[succ(ord(aTrit1))][succ(ord(aTrit2))];
 
syntax expr: .(). == .() is <-> 12;
const func trit: (in trit: aTrit1) == (in trit: aTrit2) is
return tritEquiv[succ(ord(aTrit1))][succ(ord(aTrit2))];
 
const func trit: rand (in trit: low, in trit: high) is
return trit conv (rand(ord(low), ord(high)));
 
# Begin of test code
Line 5,065 ⟶ 6,572:
writeTable(operand1 -> operand2, "->");
writeTable(operand1 == operand2, "==");
end func;</langsyntaxhighlight>
 
{{out}}
Line 5,103 ⟶ 6,610:
True | False Maybe True
</pre>
 
=={{header|SparForte}}==
As a structured script.
<syntaxhighlight lang="ada">#!/usr/local/bin/spar
pragma annotate( summary, "ternary_logic" )
@( description, "In logic, a three-valued logic (also trivalent, " )
@( description, "ternary, or trinary logic, sometimes abbreviated " )
@( description, "3VL) is any of several many-valued logic systems " )
@( description, "in which there are three truth values indicating " )
@( description, "true, false and some indeterminate third value. " )
@( see_also, "http://rosettacode.org/wiki/Ternary_logic" );
pragma annotate( author, "Ken O. Burtch" );
pragma license( unrestricted );
 
pragma restriction( no_external_commands );
 
procedure ternary_logic is
 
type ternary is (no, maybe, yes);
 
function ternary_and( left : ternary; right : ternary ) return ternary is
begin
if left < right then
return left;
else
return right;
end if;
end ternary_and;
 
function ternary_or( left : ternary; right : ternary ) return ternary is
begin
if left > right then
return left;
else
return right;
end if;
end ternary_or;
 
function ternary_not( right : ternary ) return ternary is
begin
case right is
when yes => return no;
when maybe => return maybe;
when no => return yes;
when others => put_line( "Unexpected value" );
end case;
end ternary_not;
 
function ternary_image( ternary_value : ternary ) return string is
begin
case ternary_value is
when yes => return "Yes";
when no => return "No";
when maybe => return "Maybe";
when others => put_line( "Unexpected value" );
end case;
end ternary_image;
 
begin
? "Ternary Not:"
@ "not no => " & ternary_image( ternary_not( no ) )
@ "not maybe => " & ternary_image( ternary_not( maybe ) )
@ "not yes => " & ternary_image( ternary_not( yes ) );
new_line;
 
? "Ternary And:"
@ "no and no => " & ternary_image( ternary_and( no, no ) )
@ "no and maybe => " & ternary_image( ternary_and( no, maybe ) )
@ "no and yes => " & ternary_image( ternary_and( no, yes ) )
@ "maybe and no => " & ternary_image( ternary_and( maybe, no ) )
@ "maybe and maybe => " & ternary_image( ternary_and( maybe, maybe ) )
@ "maybe and yes => " & ternary_image( ternary_and( maybe, yes ) )
@ "yes and no => " & ternary_image( ternary_and( yes, no ) )
@ "yes and maybe => " & ternary_image( ternary_and( yes, maybe ) )
@ "yes and yes => " & ternary_image( ternary_and( yes, yes ) );
new_line;
 
? "Ternary Or:"
@ "no or no => " & ternary_image( ternary_or( no, no ) )
@ "no or maybe => " & ternary_image( ternary_or( no, maybe ) )
@ "no or yes => " & ternary_image( ternary_or( no, yes ) )
@ "maybe or no => " & ternary_image( ternary_or( maybe, no ) )
@ "maybe or maybe => " & ternary_image( ternary_or( maybe, maybe ) )
@ "maybe or yes => " & ternary_image( ternary_or( maybe, yes ) )
@ "yes or no => " & ternary_image( ternary_or( yes, no ) )
@ "yes or maybe => " & ternary_image( ternary_or( yes, maybe ) )
@ "yes or yes => " & ternary_image( ternary_or( yes, yes ) );
new_line;
end ternary_logic;</syntaxhighlight>
{{out}}
<pre>
$ spar ternary_logic.sp
Ternary Not:
not no => Yes
not maybe => Maybe
not yes => No
 
Ternary And:
no and no => No
no and maybe => No
no and yes => No
maybe and no => No
maybe and maybe => Maybe
maybe and yes => Maybe
yes and no => No
yes and maybe => Maybe
yes and yes => Yes
 
Ternary Or:
no or no => No
no or maybe => Maybe
no or yes => Yes
maybe or no => Maybe
maybe or maybe => Maybe
maybe or yes => Yes
yes or no => Yes
yes or maybe => Yes
yes or yes => Yes</pre>
 
=={{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.
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
namespace eval ternary {
# Code generator
Line 5,172 ⟶ 6,797:
* false
}
}</langsyntaxhighlight>
Demonstrating:
<langsyntaxhighlight lang="tcl">namespace import ternary::*
puts "x /\\ y == x \\/ y"
puts " x | y || result"
Line 5,183 ⟶ 6,808:
puts [format " %-5s | %-5s || %-5s" $x $y $z]
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 5,198 ⟶ 6,823:
false | maybe || maybe
false | false || true
</pre>
 
 
=={{header|True BASIC}}==
{{trans|BASIC256}}
<syntaxhighlight lang="basic">
FUNCTION and3(a, b)
IF a < b then LET and3 = a else LET and3 = b
END FUNCTION
 
FUNCTION eq3(a, b)
IF a = tDontknow or b = tDontKnow then
LET eq3 = tdontknow
ELSEIF a = b then
LET eq3 = ttrue
ELSE
LET eq3 = tfalse
END IF
END FUNCTION
 
FUNCTION longname3$(i)
SELECT CASE i
CASE 1
LET longname3$ = "Don't know"
CASE 2
LET longname3$ = "True"
CASE else
LET longname3$ = "False"
END SELECT
END FUNCTION
 
FUNCTION not3(b)
LET not3 = 2-b
END FUNCTION
 
FUNCTION or3(a, b)
IF a > b then LET or3 = a else LET or3 = b
END FUNCTION
 
FUNCTION shortname3$(i)
LET shortname3$ = ("F?T")[i+1:i+1+1-1]
END FUNCTION
 
FUNCTION xor3(a, b)
LET xor3 = not3(eq3(a,b))
END FUNCTION
 
LET tfalse = 0
LET tdontknow = 1
LET ttrue = 2
 
PRINT "Nombres cortos y largos para valores lógicos ternarios:"
FOR i = tfalse to ttrue
PRINT shortname3$(i); " "; longname3$(i)
NEXT i
PRINT
PRINT "Funciones de parámetro único"
PRINT "x"; " "; "=x"; " "; "not(x)"
FOR i = tfalse to ttrue
PRINT shortname3$(i); " "; shortname3$(i); " "; shortname3$(not3(i))
NEXT i
PRINT
PRINT "Funciones de doble parámetro"
PRINT "x"; " "; "y"; " "; "x AND y"; " "; "x OR y"; " "; "x EQ y"; " "; "x XOR y"
FOR a = tfalse to ttrue
FOR b = tfalse to ttrue
PRINT shortname3$(a); " "; shortname3$(b); " ";
PRINT shortname3$(and3(a,b)); " "; shortname3$(or3(a,b)); " ";
PRINT shortname3$(eq3(a,b)); " "; shortname3$(xor3(a,b))
NEXT b
NEXT a
END
</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de Liberty BASIC.
</pre>
 
=={{header|V (Vlang)}}==
{{trans|AutoHotkey}}
Note:
 
1) V (Vlang) doesn't have a true "ternary" operator, but unlike in other languages, its "if-else if-else" can be written on a single line.
 
2) This "trick" can make code more understandable, where a traditional ternary style could be visually confusing.
 
3) Something like this, "a=1?b:a=0?1:a+b>1?1:0.5" is instead "if a == 1 {b} else if a == 0 {1} else if a + b > 1 {1} else {0.5}"
 
Below is an example of how this would look, which can be compared to traditional ternary usage:
 
<syntaxhighlight lang="v (vlang)">import math
 
fn main() {
aa := [1.0,0.5,0]
bb := [1.0,0.5,0]
mut res :=''
for a in aa {
res += '\tTernary_Not\t' + a.str() + '\t=\t' + ternary_not(a) + '\n'
}
res += '-------------\n'
for a in aa {
for b in bb {
res += a.str() + '\tTernary_And\t' + b.str() + '\t=\t' + ternary_and(a,b) + '\n'
}
}
res += '-------------\n'
for a in aa {
for b in bb {
res += a.str() + '\tTernary_or\t' + b.str() + '\t=\t' + ternary_or(a,b) + '\n'
}
}
res += '-------------\n'
for a in aa {
for b in bb {
res += a.str() + '\tTernary_then\t' + b.str() + '\t=\t' + ternary_if_then(a,b) + '\n'
}
}
res += '-------------\n'
for a in aa {
for b in bb {
res += a.str() + '\tTernary_equiv\t' + b.str() + '\t=\t' + ternary_equiv(a,b) + '\n'
}
}
res = res.replace('1.', 'true')
res = res.replace('0.5', 'maybe')
res = res.replace('0', 'false')
println(res)
}
 
fn ternary_not(a f64) string {
return math.abs(a-1).str()
}
 
fn ternary_and(a f64, b f64) string {
return if a < b {a.str()} else {b.str()}
}
 
fn ternary_or(a f64, b f64) string {
return if a > b {a.str()} else {b.str()}
}
fn ternary_if_then(a f64, b f64) string {
return if a == 1 {b.str()} else if a == 0 {'1.'} else if a + b > 1 {'1.'} else {'0.5'}
}
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'}
}</syntaxhighlight>
 
{{out}}
<pre>
Ternary_Not true = false
Ternary_Not maybe = maybe
Ternary_Not false = true
-------------
true Ternary_And true = true
true Ternary_And maybe = maybe
true Ternary_And false = false
maybe Ternary_And true = maybe
maybe Ternary_And maybe = maybe
maybe Ternary_And false = false
false Ternary_And true = false
false Ternary_And maybe = false
false Ternary_And false = false
-------------
true Ternary_or true = true
true Ternary_or maybe = true
true Ternary_or false = true
maybe Ternary_or true = true
maybe Ternary_or maybe = maybe
maybe Ternary_or false = maybe
false Ternary_or true = true
false Ternary_or maybe = maybe
false Ternary_or false = false
-------------
true Ternary_then true = true
true Ternary_then maybe = maybe
true Ternary_then false = false
maybe Ternary_then true = true
maybe Ternary_then maybe = maybe
maybe Ternary_then false = maybe
false Ternary_then true = true
false Ternary_then maybe = true
false Ternary_then false = true
-------------
true Ternary_equiv true = true
true Ternary_equiv maybe = maybe
true Ternary_equiv false = false
maybe Ternary_equiv true = maybe
maybe Ternary_equiv maybe = true
maybe Ternary_equiv false = maybe
false Ternary_equiv true = false
false Ternary_equiv maybe = maybe
false Ternary_equiv false = true
</pre>
 
=={{header|Wren}}==
<syntaxhighlight lang="wren">var False = -1
var Maybe = 0
var True = 1
var Chrs = ["F", "M", "T"]
 
class Trit {
construct new(v) {
if (v != False && v != Maybe && v != True) Fiber.abort("Invalid argument.")
_v = v
}
 
v { _v }
 
! { Trit.new(-_v) }
 
&(other) { (_v < other.v) ? this : other }
 
|(other) { (_v > other.v) ? this : other }
 
>>(other) { (-_v > other.v) ? !this : other }
 
==(other) { Trit.new(_v * other.v) }
 
toString { Chrs[_v + 1] }
}
 
var trits = [Trit.new(True), Trit.new(Maybe), Trit.new(False)]
 
System.print("not")
System.print("-------")
for (t in trits) System.print(" %(t) | %(!t)")
 
System.print("\nand | T M F")
System.print("-------------")
for (t in trits) {
System.write(" %(t) | ")
for (u in trits) System.write("%(t & u) ")
System.print()
}
 
System.print("\nor | T M F")
System.print("-------------")
for (t in trits) {
System.write(" %(t) | ")
for (u in trits) System.write("%(t | u) ")
System.print()
}
 
System.print("\nimp | T M F")
System.print("-------------")
for (t in trits) {
System.write(" %(t) | ")
for (u in trits) System.write("%(t >> u) ")
System.print()
}
 
System.print("\neqv | T M F")
System.print("-------------")
for (t in trits) {
System.write(" %(t) | ")
for (u in trits) System.write("%(t == u) ")
System.print()
}</syntaxhighlight>
 
{{out}}
<pre>
not
-------
T | F
M | M
F | T
 
and | T M F
-------------
T | T M F
M | M M F
F | F F F
 
or | T M F
-------------
T | T T T
M | T M M
F | T M F
 
imp | T M F
-------------
T | T M F
M | T M M
F | T T T
 
eqv | T M F
-------------
T | T M F
M | M M M
F | F M T
</pre>
 
=={{header|Yabasic}}==
{{trans|BASIC256}}
<syntaxhighlight lang="yabasic">
tFalse = 0
tDontKnow = 1
tTrue = 2
 
sub not3(b)
return 2-b
end sub
 
sub and3(a,b)
return min(a,b)
end sub
 
sub or3(a,b)
return max(a,b)
end sub
 
sub eq3(a,b)
if a = tDontKnow or b = tDontKnow then
return tDontKnow
elsif a = b then
return tTrue
else
return tFalse
end if
end sub
 
sub xor3(a,b)
return not3(eq3(a,b))
end sub
 
sub shortName3$(i)
return mid$("F?T", i+1, 1)
end sub
 
sub longName3$(i)
switch i
case 1
return "Don't know"
case 2
return "True"
default
return "False"
end switch
end sub
 
print "Nombres cortos y largos para valores logicos ternarios:"
for i = tFalse to tTrue
print shortName3$(i), " ", longName3$(i)
next i
print
 
print "Funciones de parametro unico"
print "x", " ", "=x", " ", "not(x)"
for i = tFalse to tTrue
print shortName3$(i), " ", shortName3$(i), " ", shortName3$(not3(i))
next i
print
 
print "Funciones de doble parametro"
print "x"," ","y"," ","x AND y"," ","x OR y"," ","x EQ y"," ","x XOR y"
for a = tFalse to tTrue
for b = tFalse to tTrue
print shortName3$(a), " ", shortName3$(b), " ";
print shortName3$(and3(a,b)), " ", shortName3$(or3(a,b)), " ";
print shortName3$(eq3(a,b)), " ", shortName3$(xor3(a,b))
next b
next a
end
</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de Liberty BASIC.
</pre>
 
3

edits