Ternary logic: Difference between revisions

103,438 bytes added ,  26 days ago
m
no edit summary
(added racket)
mNo edit summary
 
(133 intermediate revisions by 51 users not shown)
Line 1:
{{task|Logic}}{{wikipedia|Ternary logic}}
{{wikipedia|Ternary logic}}
In [[wp:logic|logic]], a '''three-valued logic''' (also '''trivalent''', '''ternary''', or '''trinary logic''', sometimes abbreviated '''3VL''') is any of several [[wp:many-valued logic|many-valued logic]] systems in which there are three [[wp:truth value|truth value]]s indicating ''true'', ''false'' and some indeterminate third value. This is contrasted with the more commonly known [[wp:Principle of bivalence|bivalent]] logics (such as classical sentential or [[wp:boolean logic|boolean logic]]) which provide only for ''true'' and ''false''. Conceptual form and basic ideas were initially created by [[wp:Jan Łukasiewicz|Łukasiewicz]], [[wp:C. I. Lewis|Lewis]] and [[wp:Sulski|Sulski]]. These were then re-formulated by [[wp:Grigore Moisil|Grigore Moisil]] in an axiomatic algebraic form, and also extended to ''n''-valued logics in 1945.
 
<br>
In [[wp:logic|logic]], a '''three-valued logic''' (also '''trivalent''', '''ternary''', or '''trinary logic''', sometimes abbreviated '''3VL''') is any of several [[wp:many-valued logic|many-valued logic]] systems in which there are three [[wp:truth value|truth value]]s indicating ''true'', ''false'' and some indeterminate third value.
 
This is contrasted with the more commonly known [[wp:Principle of bivalence|bivalent]] logics (such as classical sentential or [[wp:boolean logic|boolean logic]]) which provide only for ''true'' and ''false''.
 
Conceptual form and basic ideas were initially created by [[wp:Jan Łukasiewicz|Łukasiewicz]], [[wp:C. I. Lewis|Lewis]] and [[wp:Sulski|Sulski]].
 
These were then re-formulated by [[wp:Grigore Moisil|Grigore Moisil]] in an axiomatic algebraic form, and also extended to ''n''-valued logics in 1945.
{|
|+'''Example ''Ternary Logic Operators'' in ''Truth Tables'':'''
Line 73 ⟶ 82:
|}
|}
 
'''Task:'''
 
;Task:
* Define a new type that emulates ''ternary logic'' by storing data '''trits'''.
* Given all the binary logic operators of the original programming language, reimplement these operators for the new ''Ternary logic'' type '''trit'''.
* Generate a sampling of results using '''trit''' variables.
* [[wp:Kudos|Kudos]] for actually thinking up a test case algorithm where ''ternary logic'' is intrinsically useful, optimises the test case algorithm and is preferable to binary logic.
 
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>
Note: &nbsp; '''[[wp:Setun|Setun]]''' &nbsp; (Сетунь) was a &nbsp; [[wp:balanced ternary|balanced ternary]] &nbsp; computer developed in 1958 at &nbsp; [[wp:Moscow State University|Moscow State University]]. &nbsp; The device was built under the lead of &nbsp; [[wp:Sergei Sobolev|Sergei Sobolev]] &nbsp; and &nbsp; [[wp:Nikolay Brusentsov|Nikolay Brusentsov]]. &nbsp; It was the only modern &nbsp; [[wp:ternary computer|ternary computer]], &nbsp; 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 97 ⟶ 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 162 ⟶ 303:
end Implies;
 
end Logic;</langsyntaxhighlight>
 
Finally, a sample program:
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO, Logic;
 
procedure Test_Tri_Logic is
Line 199 ⟶ 340:
Truth_Table(F => Equivalent'Access, Name => "Eq");
Truth_Table(F => Implies'Access, Name => "Implies");
end Test_Tri_Logic;</langsyntaxhighlight>
 
{{out}}
The output:<pre>X | Not(X)
<pre>X | Not(X)
T | F
? | ?
Line 224 ⟶ 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 322 ⟶ 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 347 ⟶ 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 417 ⟶ 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}}
'''Output:'''
<pre>
Comparitive table of coercions:
Line 474 ⟶ 616:
---+---+---+---
⌈ | ⌈ | ⌈ | ⌈
</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}}==
<syntaxhighlight lang="autohotkey">Ternary_Not(a){
SetFormat, Float, 2.1
return Abs(a-1)
}
 
Ternary_And(a,b){
return a<b?a:b
}
 
Ternary_Or(a,b){
return a>b?a:b
}
 
Ternary_IfThen(a,b){
return a=1?b:a=0?1:a+b>1?1:0.5
}
 
Ternary_Equiv(a,b){
return a=b?1:a=1?b:b=1?a:0.5
}</syntaxhighlight>
Examples:<syntaxhighlight lang="autohotkey">aa:=[1,0.5,0]
bb:=[1,0.5,0]
 
for index, a in aa
Res .= "`tTernary_Not`t" a "`t=`t" Ternary_Not(a) "`n"
Res .= "-------------`n"
 
for index, a in aa
for index, b in bb
Res .= a "`tTernary_And`t" b "`t=`t" Ternary_And(a,b) "`n"
Res .= "-------------`n"
 
for index, a in aa
for index, b in bb
Res .= a "`tTernary_or`t" b "`t=`t" Ternary_Or(a,b) "`n"
Res .= "-------------`n"
 
for index, a in aa
for index, b in bb
Res .= a "`tTernary_then`t" b "`t=`t" Ternary_IfThen(a,b) "`n"
Res .= "-------------`n"
 
for index, a in aa
for index, b in bb
Res .= a "`tTernary_equiv`t" b "`t=`t" Ternary_Equiv(a,b) "`n"
 
StringReplace, Res, Res, 1, true, all
StringReplace, Res, Res, 0.5, maybe, all
StringReplace, Res, Res, 0, false, all
MsgBox % Res
return</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|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 523 ⟶ 902:
PRINT "TRUE EQV TRUE = " FN(mytrit.teqv)("TRUE","TRUE")
PROC_discard(mytrit{})</langsyntaxhighlight>
{{out}}
'''Output:'''
<pre>
Testing NOT:
Line 554 ⟶ 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 628 ⟶ 1,081:
return 0;
}</langsyntaxhighlight>
 
{{out}}
Output:
<lang textpre>Not T: F
Not ?: ?
Not F: T
Line 673 ⟶ 1,126:
F Equiv T: F
F Equiv ?: ?
F Equiv F: T</langpre>
 
===Using functions===
<langsyntaxhighlight lang="c">#include <stdio.h>
 
typedef enum { t_F = -1, t_M, t_T } trit;
Line 711 ⟶ 1,164:
 
return 0;
}</syntaxhighlight>
}</lang>output<lang>[Not]
{{out}}
<pre>[Not]
F | T
? | ?
Line 742 ⟶ 1,197:
F | T T T
? | ? ? T
T | F ? T</langpre>
 
===Variable truthfulness===
Represent each possible truth value as a floating point value x,
Represent each possible truth value as a floating point value x, where the var has x chance of being true and 1 - x chance of being false. When using <code>if3</code> conditional on a potential truth varible, the result is randomly sampled to true or false according to the chance. (This description is definitely very confusing perhaps).
where the var has x chance of being true and 1 - x chance of being false.
<lang c>#include <stdio.h>
When using <code>if3</code> conditional on a potential truth varible,
the result is randomly sampled to true or false according to the chance.
(This description is definitely very confusing perhaps).
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 800 ⟶ 1,259:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">using System;
 
/// <summary>
Line 847 ⟶ 1,306:
}
}
}</langsyntaxhighlight>
{{out}}
Output:
<pre>¬True = False
True & True = True
Line 888 ⟶ 1,347:
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.
<syntaxhighlight lang="cpp">#include <iostream>
#include <stdlib.h>
 
class trit {
public:
static const trit False, Maybe, True;
 
trit operator !() const {
return static_cast<Value>(-value);
}
 
trit operator &&(const trit &b) const {
return (value < b.value) ? value : b.value;
}
 
trit operator ||(const trit &b) const {
return (value > b.value) ? value : b.value;
}
 
trit operator >>(const trit &b) const {
return -value > b.value ? static_cast<Value>(-value) : b.value;
}
 
trit operator ==(const trit &b) const {
return static_cast<Value>(value * b.value);
}
 
char chr() const {
return "F?T"[value + 1];
}
 
protected:
typedef enum { FALSE=-1, MAYBE, TRUE } Value;
 
Value value;
 
trit(const Value value) : value(value) { }
};
 
std::ostream& operator<<(std::ostream &os, const trit &t)
{
os << t.chr();
return os;
}
 
const trit trit::False = trit(trit::FALSE);
const trit trit::Maybe = trit(trit::MAYBE);
const trit trit::True = trit(trit::TRUE);
 
int main(int, char**) {
const trit trits[3] = { trit::True, trit::Maybe, trit::False };
 
#define for_each(name) \
for (size_t name=0; name<3; ++name)
 
#define show_op(op) \
std::cout << std::endl << #op << " "; \
for_each(a) std::cout << ' ' << trits[a]; \
std::cout << std::endl << " -------"; \
for_each(a) { \
std::cout << std::endl << trits[a] << " |"; \
for_each(b) std::cout << ' ' << (trits[a] op trits[b]); \
} \
std::cout << std::endl;
 
std::cout << "! ----" << std::endl;
for_each(a) std::cout << trits[a] << " | " << !trits[a] << std::endl;
 
show_op(&&);
show_op(||);
show_op(>>);
show_op(==);
return EXIT_SUCCESS;
}</syntaxhighlight>
{{out}}
<pre>! ----
T | F
? | ?
F | T
 
&& T ? F
-------
T | T ? F
? | ? ? F
F | F F F
 
|| T ? F
-------
T | T T T
? | T ? ?
F | T ? F
 
>> T ? F
-------
T | T ? F
? | T ? ?
F | T T T
 
== T ? F
-------
T | T ? F
? | ? ? ?
F | F ? T</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 920 ⟶ 1,485:
(print-table #'tri-or "OR")
(print-table #'tri-imply "IMPLY")
(print-table #'tri-eq "EQUAL")</langsyntaxhighlight>output<lang>NOT:
{{out}}
<pre>NOT:
T | F
? | ?
Line 951 ⟶ 1,518:
T | T ? F
? | ? ? ?
F | F ? T</langpre>
 
=={{header|D}}==
Partial translation of a C entry:
<langsyntaxhighlight lang="d">import std.stdio;
 
struct Trit {
Line 1,022 ⟶ 1,589:
showOperation!"=="("Equiv");
showOperation!"==>"("Imply");
}</langsyntaxhighlight>
{{out}}
<pre>[Not]
Line 1,065 ⟶ 1,632:
 
=={{header|Delphi}}==
<langsyntaxhighlight lang="delphi">unit TrinaryLogic;
 
interface
Line 1,120 ⟶ 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,149 ⟶ 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|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)
{
if (v != nil)
{
_value := cast bool(v);
}
}
Trit equivalent(b)
{
var val2 := cast bool(b) \ back(nil);
 
if (val2 != nil && _value != nil)
{
^ _value.equal(val2)
};
 
^ nilValue;
}
Trit Inverted
= _value.Inverted \ back(nilValue);
Trit and(b)
{
if (nil == _value)
{
^ b.and(nil) \ back(nilValue)
}
else
{
^ _value.and(b) \ back(nilValue)
}
}
Trit or(b)
{
if (nil == _value)
{
^ b.or(nilValue) \ back(nilValue)
}
else
{
^ _value.or(b) \ back(nilValue)
}
}
Trit implies(b)
= self.Inverted.or(b);
string toPrintable() = _value.toPrintable() \ back("maybe");
}
public program()
{
List<Trit> values := new Trit[]{true, nilValue, false};
values.forEach::(left)
{
console.printLine("¬",left," = ", left.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>
{{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|Erlang}}==
<syntaxhighlight lang="erlang">% Implemented by Arjun Sunel
-module(ternary).
-export([main/0, nott/1, andd/2,orr/2, then/2, equiv/2]).
 
main() ->
{ok, [A]} = io:fread("Enter A: ","~s"),
{ok, [B]} = io:fread("Enter B: ","~s"),
andd(A,B).
 
nott(S) ->
if
S=="T" ->
io : format("F\n");
 
S=="F" ->
io : format("T\n");
 
true ->
io: format("?\n")
end.
andd(A, B) ->
if
A=="T", B=="T" ->
io : format("T\n");
A=="F"; B=="F" ->
io : format("F\n");
 
true ->
io: format("?\n")
end.
 
 
orr(A, B) ->
if
A=="T"; B=="T" ->
io : format("T\n");
A=="?"; B=="?" ->
io : format("?\n");
 
true ->
io: format("F\n")
end.
 
then(A, B) ->
if
B=="T" ->
io : format("T\n");
A=="?" ->
io : format("?\n");
 
A=="F" ->
io :format("T\n");
B=="F" ->
io:format("F\n");
true ->
io: format("?\n")
end.
 
equiv(A, B) ->
if
A=="?" ->
io : format("?\n");
A=="F" ->
io : format("~s\n", [nott(B)]);
 
true ->
io: format("~s\n", [B])
end.
</syntaxhighlight>
 
=={{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,197 ⟶ 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,210 ⟶ 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">
!-*- mode: compilation; default-directory: "/tmp/" -*-
!Compilation started at Mon May 20 23:05:46
!
!a=./f && make $a && $a < unixdict.txt
!gfortran -std=f2003 -Wall -ffree-form f.f03 -o f
!
!ternary not
! 1.0 0.5 0.0
!
!
!ternary and
! 0.0 0.0 0.0
! 0.0 0.5 0.5
! 0.0 0.5 1.0
!
!
!ternary or
! 0.0 0.5 1.0
! 0.5 0.5 1.0
! 1.0 1.0 1.0
!
!
!ternary if
! 1.0 1.0 1.0
! 0.5 0.5 1.0
! 0.0 0.5 1.0
!
!
!ternary eq
! 1.0 0.5 0.0
! 0.5 0.5 0.5
! 0.0 0.5 1.0
!
!
!Compilation finished at Mon May 20 23:05:46
 
 
!This program is based on the j implementation
!not=: -.
!and=: <.
!or =: >.
!if =: (>. -.)"0~
!eq =: (<.&-. >. <.)"0
 
module trit
 
real, parameter :: true = 1, false = 0, maybe = 0.5
 
contains
 
real function tnot(y)
real, intent(in) :: y
tnot = 1 - y
end function tnot
 
real function tand(x, y)
real, intent(in) :: x, y
tand = min(x, y)
end function tand
 
real function tor(x, y)
real, intent(in) :: x, y
tor = max(x, y)
end function tor
 
real function tif(x, y)
real, intent(in) :: x, y
tif = tor(y, tnot(x))
end function tif
 
real function teq(x, y)
real, intent(in) :: x, y
teq = tor(tand(tnot(x), tnot(y)), tand(x, y))
end function teq
 
end module trit
 
program ternaryLogic
use trit
integer :: i
real, dimension(3) :: a = [false, maybe, true] ! (/ ... /)
write(6,'(/a)')'ternary not' ; write(6, '(3f4.1/)') (tnot(a(i)), i = 1 , 3)
write(6,'(/a)')'ternary and' ; call table(tand, a, a)
write(6,'(/a)')'ternary or' ; call table(tor, a, a)
write(6,'(/a)')'ternary if' ; call table(tif, a, a)
write(6,'(/a)')'ternary eq' ; call table(teq, a, a)
 
contains
 
subroutine table(u, x, y) ! for now, show the table.
real, external :: u
real, dimension(3), intent(in) :: x, y
integer :: i, j
write(6, '(3(3f4.1/))') ((u(x(i), y(j)), j=1,3), i=1,3)
end subroutine table
 
end program ternaryLogic
</syntaxhighlight>
 
=={{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.
Note Since we use a balanced range -1,0,1 multiplication equals EQU
<syntaxhighlight lang="pascal">{$mode objfpc}
unit ternarylogic;
 
interface
type
{ ternary type, balanced }
trit = (tFalse=-1, tMaybe=0, tTrue=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 =
((tFalse,tFalse,tFalse),
(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 =
((tFalse,tMaybe,tTrue),
(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 =(tTrue,tMaybe,tFalse);
begin
Result:= LookUpNot[a];
end;
operator xor (const a,b:trit):trit;
const LookupXor:array[trit,trit] of trit =
((tFalse,tMaybe,tTrue),
(tMaybe,tMaybe,tMaybe),
(tTrue,tMaybe,tFalse));
begin
Result := LookupXor[a,b];
end;
 
operator * (const a,b:trit):trit;
begin
result := not (a xor b);
end;
 
{ imp ==>}
operator >< (const a,b:trit):trit;
begin
result := not(a) or b;
end;
end.
</syntaxhighlight>
<syntaxhighlight lang="pascal">program ternarytests;
{$mode objfpc}
uses
ternarylogic;
begin
writeln(' a AND b');
writeln('F':7,'U':7, 'T':7);
writeln('F|',tFalse and tFalse:7,tFalse and tMaybe:7,tFalse and tTrue:7);
writeln('U|',tMaybe and tFalse:7,tMaybe and tMaybe:7,tMaybe and tTrue:7);
writeln('T|',tTrue and tFalse:7,tTrue and tMaybe:7,tTrue and tTrue:7);
writeln;
writeln(' a OR b');
writeln('F':7,'U':7, 'T':7);
writeln('F|',tFalse or tFalse:7,tFalse or tMaybe:7,tFalse or tTrue:7);
writeln('U|',tMaybe or tFalse:7,tMaybe or tMaybe:7,tMaybe or tTrue:7);
writeln('T|',tTrue or tFalse:7,tTrue or tMaybe:7,tTrue or tTrue:7);
writeln;
writeln(' NOT a');
writeln('F|',not tFalse:7);
writeln('U|',not tMaybe:7);
writeln('T|',not tTrue:7);
writeln;
writeln(' a XOR b');
writeln('F':7,'U':7, 'T':7);
writeln('F|',tFalse xor tFalse:7,tFalse xor tMaybe:7,tFalse xor tTrue:7);
writeln('U|',tMaybe xor tFalse:7,tMaybe xor tMaybe:7,tMaybe xor tTrue:7);
writeln('T|',tTrue xor tFalse:7,tTrue xor tMaybe:7,tTrue xor tTrue:7);
writeln;
writeln('equality/equivalence and multiplication');
writeln('F':7,'U':7, 'T':7);
writeln('F|', tFalse * tFalse:7,tFalse * tMaybe:7, tFalse * tTrue:7);
writeln('U|', tMaybe * tFalse:7,tMaybe * tMaybe:7,tMaybe * tTrue:7);
writeln('T|', tTrue * tFalse:7, tTrue * tMaybe:7, tTrue * tTrue:7);
writeln;
writeln('IMP. a.k.a. IfThen -> not(a) or b');
writeln('F':7,'U':7, 'T':7);
writeln('T|',tTrue >< tTrue:7,tTrue >< tMaybe:7,tTrue >< tFalse:7);
writeln('U|',tMaybe >< tTrue:7,tMaybe >< tMaybe:7,tMaybe >< tFalse:7);
writeln('F|',tFalse >< tTrue:7, tFalse >< tMaybe:7,tFalse >< tFalse:7);
writeln;
end.</syntaxhighlight>
<pre>
Output:
a AND b
F U T
F|tFalse tFalse tFalse
U|tFalse tMaybe tMaybe
T|tFalse tMaybe tTrue
 
a OR b
F U T
F|tFalse tMaybe tTrue
U|tMaybe tMaybe tTrue
T|tTrue tTrue tTrue
 
NOT a
F|tTrue
U|tMaybe
T|tFalse
 
a XOR b
F U T
F|tFalse tMaybe tTrue
U|tMaybe tMaybe tMaybe
T|tTrue tMaybe tFalse
 
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.
 
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.
 
The option to show Fōrmulæ programs and their results is showing images. Unfortunately images cannot be uploaded in Rosetta Code.
 
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.
 
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,221 ⟶ 2,458:
 
const (
trFalse trit = iota - 1
trMaybe
trTrue
Line 1,288 ⟶ 2,525:
}
}
}</langsyntaxhighlight>
{{out}}
Output:
<pre>
t not t
Line 1,332 ⟶ 2,569:
=={{header|Groovy}}==
Solution:
<langsyntaxhighlight lang="groovy">enum Trit {
TRUE, MAYBE, FALSE
Line 1,349 ⟶ 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 1,391 ⟶ 2,628:
Trit.values().each { b -> printf ('%6s', a.equiv(b)) }
println()
}</langsyntaxhighlight>
 
{{out}}
Output:
<pre>AND
TRUE MAYBE FALSE
Line 1,431 ⟶ 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 1,467 ⟶ 2,704:
where header = map (:[]) (take ((length $ head xs) - 1) ['A'..]) ++ [name]
 
pad s = s ++ replicate (5 - length s) ' '</langsyntaxhighlight>
 
{{out}}
Output:
<pre>A not
True False
Line 1,520 ⟶ 2,757:
 
=={{header|Icon}} and {{header|Unicon}}==
The following example works in both Icon and Unicon. There are a couple of comments on the code that pertain to the task requirements:
There are a couple of comments on the code that pertain to the task requirements:
* Strictly speaking there are no binary values in Icon and Unicon. There are a number of flow control operations that result in expression success (and a result) or failure which affects flow. As a result there really isn't a set of binary operators to map into ternary. The example provides the minimum required by the task plus xor.
* The code below does not define a data type as it doesn't really make sense in this case. Icon and Unicon can create records which would be overkill and clumsy in this case. Unicon can create objects which would also be overkill. The only remaining option is to reinterpret one of the existing types as ternary values. The code below implements balanced ternary values as integers in order to simplify several of the functions.
Line 1,526 ⟶ 2,764:
 
 
<langsyntaxhighlight Iconlang="icon">$define TRUE 1
$define FALSE -1
$define UNKNOWN 0
Line 1,587 ⟶ 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}}
[http://www.cs.arizona.edu/icon/library/src/procs/printf.icn printf.icn provides support for the printf family of functions]
 
{{out}}
Output:<pre>unary function=not3:
<pre>unary function=not3:
T : F
F : T
Line 1,637 ⟶ 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 1,666 ⟶ 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 1,703 ⟶ 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 1,720 ⟶ 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 1,791 ⟶ 3,030:
}
}
}</langsyntaxhighlight>
{{out}}
Output:
<pre>not TRUE: FALSE
not MAYBE: MAYBE
Line 1,805 ⟶ 3,044:
FALSE and MAYBE: FALSE FALSE or MAYBE: MAYBE FALSE implies MAYBE: TRUE FALSE = MAYBE: MAYBE
FALSE and FALSE: FALSE FALSE or FALSE: FALSE FALSE implies FALSE: TRUE FALSE = FALSE: TRUE</pre>
 
=={{header|JavaScript}}==
Let's use the trit already available in JavaScript:
true, false (both boolean) and undefined…
<syntaxhighlight lang="javascript">var L3 = new Object();
 
L3.not = function(a) {
if (typeof a == "boolean") return !a;
if (a == undefined) return undefined;
throw("Invalid Ternary Expression.");
}
 
L3.and = function(a, b) {
if (typeof a == "boolean" && typeof b == "boolean") return a && b;
if ((a == true && b == undefined) || (a == undefined && b == true)) return undefined;
if ((a == false && b == undefined) || (a == undefined && b == false)) return false;
if (a == undefined && b == undefined) return undefined;
throw("Invalid Ternary Expression.");
}
 
L3.or = function(a, b) {
if (typeof a == "boolean" && typeof b == "boolean") return a || b;
if ((a == true && b == undefined) || (a == undefined && b == true)) return true;
if ((a == false && b == undefined) || (a == undefined && b == false)) return undefined;
if (a == undefined && b == undefined) return undefined;
throw("Invalid Ternary Expression.");
}
 
// A -> B is equivalent to -A or B
L3.ifThen = function(a, b) {
return L3.or(L3.not(a), b);
}
 
// A <=> B is equivalent to (A -> B) and (B -> A)
L3.iff = function(a, b) {
return L3.and(L3.ifThen(a, b), L3.ifThen(b, a));
}
</syntaxhighlight>
… and try these:
<syntaxhighlight lang="text">
L3.not(true) // false
L3.not(var a) // undefined
 
L3.and(true, a) // undefined
 
L3.or(a, 2 == 3) // false
 
L3.ifThen(true, a) // undefined
 
L3.iff(a, 2 == 2) // undefined
</syntaxhighlight>
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}}==
jq itself does not have an extensible type system, so we'll use false, "maybe", and true
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. <syntaxhighlight lang="jq">def ternary_nand(a; b):
if a == false or b == false then true
elif a == "maybe" or b == "maybe" then "maybe"
else false
end ;
 
def ternary_not(a): ternary_nand(a; a);
 
def ternary_or(a; b): ternary_nand( ternary_not(a); ternary_not(b) );
 
def ternary_nor(a; b): ternary_not( ternary_or(a;b) );
 
def ternary_and(a; b): ternary_not( ternary_nand(a; b) );
 
def ternary_imply(this; that):
ternary_nand(this, ternary_not(that));
 
def ternary_equiv(this; that):
ternary_or( ternary_and(this; that); ternary_nor(this; that) );
 
def display_and(a; b):
a as $a | b as $b
| "\($a) and \($b) is \( ternary_and($a; $b) )";
def display_equiv(a; b):
a as $a | b as $b
| "\($a) equiv \($b) is \( ternary_equiv($a; $b) )";
# etc etc
 
# Invoke the display functions:
display_and( (false, "maybe", true ); (false, "maybe", true) ),
display_equiv( (false, "maybe", true ); (false, "maybe", true) ),
"etc etc"
</syntaxhighlight>
{{out}}
<pre>"false and false is false"
"false and maybe is false"
"false and true is false"
"maybe and false is false"
"maybe and maybe is maybe"
"maybe and true is maybe"
"true and false is false"
"true and maybe is maybe"
"true and true is true"
"false equiv false is true"
"false equiv maybe is maybe"
"false equiv true is false"
"maybe equiv false is maybe"
"maybe equiv maybe is maybe"
"maybe equiv true is maybe"
"true equiv false is false"
"true equiv maybe is maybe"
"true equiv true is true"
"etc etc"
</pre>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<syntaxhighlight lang="julia">@enum Trit False Maybe True
const trits = (False, Maybe, True)
 
Base.:!(a::Trit) = a == False ? True : a == Maybe ? Maybe : False
∧(a::Trit, b::Trit) = a == b == True ? True : (a, b) ∋ False ? False : Maybe
∨(a::Trit, b::Trit) = a == b == False ? False : (a, b) ∋ True ? True : Maybe
⊃(a::Trit, b::Trit) = a == False || b == True ? True : (a, b) ∋ Maybe ? Maybe : False
≡(a::Trit, b::Trit) = (a, b) ∋ Maybe ? Maybe : a == b ? True : False
 
println("Not (!):")
println(join(@sprintf("%10s%s is %5s", "!", t, !t) for t in trits))
println("And (∧):")
for a in trits
println(join(@sprintf("%10s ∧ %5s is %5s", a, b, a ∧ b) for b in trits))
end
println("Or (∨):")
for a in trits
println(join(@sprintf("%10s ∨ %5s is %5s", a, b, a ∨ b) for b in trits))
end
println("If Then (⊃):")
for a in trits
println(join(@sprintf("%10s ⊃ %5s is %5s", a, b, a ⊃ b) for b in trits))
end
println("Equivalent (≡):")
for a in trits
println(join(@sprintf("%10s ≡ %5s is %5s", a, b, a ≡ b) for b in trits))
end</syntaxhighlight>
 
{{out}}
<pre>Not (!):
!False is True !Maybe is Maybe !True is False
And (∧):
False ∧ False is False False ∧ Maybe is False False ∧ True is False
Maybe ∧ False is False Maybe ∧ Maybe is Maybe Maybe ∧ True is Maybe
True ∧ False is False True ∧ Maybe is Maybe True ∧ True is True
Or (∨):
False ∨ False is False False ∨ Maybe is Maybe False ∨ True is True
Maybe ∨ False is Maybe Maybe ∨ Maybe is Maybe Maybe ∨ True is True
True ∨ False is True True ∨ Maybe is True True ∨ True is True
If Then (⊃):
False ⊃ False is True False ⊃ Maybe is True False ⊃ True is True
Maybe ⊃ False is Maybe Maybe ⊃ Maybe is Maybe Maybe ⊃ True is True
True ⊃ False is False True ⊃ Maybe is Maybe True ⊃ True is True
Equivalent (≡):
False ≡ False is True False ≡ Maybe is Maybe False ≡ True is False
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}}==
<syntaxhighlight lang="scala">// version 1.1.2
 
enum class Trit {
TRUE, MAYBE, FALSE;
operator fun not() = when (this) {
TRUE -> FALSE
MAYBE -> MAYBE
FALSE -> TRUE
}
 
infix fun and(other: Trit) = when (this) {
TRUE -> other
MAYBE -> if (other == FALSE) FALSE else MAYBE
FALSE -> FALSE
}
 
infix fun or(other: Trit) = when (this) {
TRUE -> TRUE
MAYBE -> if (other == TRUE) TRUE else MAYBE
FALSE -> other
}
 
infix fun imp(other: Trit) = when (this) {
TRUE -> other
MAYBE -> if (other == TRUE) TRUE else MAYBE
FALSE -> TRUE
}
 
infix fun eqv(other: Trit) = when (this) {
TRUE -> other
MAYBE -> MAYBE
FALSE -> !other
}
 
override fun toString() = this.name[0].toString()
}
 
fun main(args: Array<String>) {
val ta = arrayOf(Trit.TRUE, Trit.MAYBE, Trit.FALSE)
 
// not
println("not")
println("-------")
for (t in ta) println(" $t | ${!t}")
println()
 
// and
println("and | T M F")
println("-------------")
for (t in ta) {
print(" $t | ")
for (tt in ta) print("${t and tt} ")
println()
}
println()
 
// or
println("or | T M F")
println("-------------")
for (t in ta) {
print(" $t | ")
for (tt in ta) print("${t or tt} ")
println()
}
println()
 
// imp
println("imp | T M F")
println("-------------")
for (t in ta) {
print(" $t | ")
for (tt in ta) print("${t imp tt} ")
println()
}
println()
 
// eqv
println("eqv | T M F")
println("-------------")
for (t in ta) {
print(" $t | ")
for (tt in ta) print("${t eqv tt} ")
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|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 1,878 ⟶ 3,643:
longName3$ = word$("False,Don't know,True", i+1, ",")
end function
</langsyntaxhighlight>
 
{{out}}
Output:
<pre>
Short and long names for ternary logic values
Line 1,906 ⟶ 3,671:
</pre>
 
=={{header|MathematicaM2000 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>
 
=={{header|Maple}}==
The logic system in Maple is implicitly ternary with truth values '''true''', '''false''', and '''FAIL'''.
 
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'''.
 
<syntaxhighlight lang="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] );</syntaxhighlight>
 
{{Out}}
 
<syntaxhighlight lang="maple">> tv := [true, false, FAIL];
tv := [true, false, FAIL]
 
> NotTable := Array(1..3, i->not tv[i] );
NotTable := [false, true, FAIL]
 
> AndTable := Array(1..3, 1..3, (i,j)->tv[i] and tv[j] );
[true false FAIL ]
[ ]
AndTable := [false false false]
[ ]
[FAIL false FAIL ]
 
> OrTable := Array(1..3, 1..3, (i,j)->tv[i] or tv[j] );
[true true true]
[ ]
OrTable := [true false FAIL]
[ ]
[true FAIL FAIL]
 
> XorTable := Array(1..3, 1..3, (i,j)->tv[i] xor tv[j] );
[false true FAIL]
[ ]
XorTable := [true false FAIL]
[ ]
[FAIL FAIL FAIL]
 
> ImpliesTable := Array(1..3, 1..3, (i,j)->tv[i] implies tv[j] );
[true false FAIL]
[ ]
ImpliesTable := [true true true]
[ ]
[true FAIL FAIL]</syntaxhighlight>
 
=={{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 1,919 ⟶ 3,942:
Null}}}, {{{Null}}, {trits}}, {List /@ trits,
Outer[operator, trits, trits]}}]], {operator, {And, Or, Nand,
Nor, Xor, Xnor, Implies, Equivalent}}]</langsyntaxhighlight>
{{out}}
Output:
<pre>Not
True False
Maybe Maybe
False True
 
 
 
And
Line 1,933 ⟶ 3,954:
Maybe Maybe Maybe False
False False False False
 
 
 
Line 1,941 ⟶ 3,961:
Maybe True Maybe Maybe
False True Maybe False
 
 
 
Line 1,949 ⟶ 3,968:
Maybe Maybe Maybe True
False True True True
 
 
 
Line 1,957 ⟶ 3,975:
Maybe False Maybe Maybe
False False Maybe True
 
 
 
Line 1,965 ⟶ 3,982:
Maybe Maybe Maybe Maybe
False True Maybe False
 
 
 
Line 1,981 ⟶ 3,997:
Maybe True Maybe Maybe
False True True True
 
 
 
Line 1,988 ⟶ 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 2,007 ⟶ 4,020:
 
''a'', ''b'' ∈ {-1, 0, 1}.
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">type Trit* = enum ttrue, tmaybe, tfalse
 
proc `$`*(a: Trit): string =
case a
of ttrue: "T"
of tmaybe: "?"
of tfalse: "F"
 
proc `not`*(a: Trit): Trit =
case a
of ttrue: tfalse
of tmaybe: tmaybe
of tfalse: ttrue
 
proc `and`*(a, b: Trit): Trit =
const t: array[Trit, array[Trit, Trit]] =
[ [ttrue, tmaybe, tfalse]
, [tmaybe, tmaybe, tfalse]
, [tfalse, tfalse, tfalse] ]
t[a][b]
 
proc `or`*(a, b: Trit): Trit =
const t: array[Trit, array[Trit, Trit]] =
[ [ttrue, ttrue, ttrue]
, [ttrue, tmaybe, tmaybe]
, [ttrue, tmaybe, tfalse] ]
t[a][b]
 
proc then*(a, b: Trit): Trit =
const t: array[Trit, array[Trit, Trit]] =
[ [ttrue, tmaybe, tfalse]
, [ttrue, tmaybe, tmaybe]
, [ttrue, ttrue, ttrue] ]
t[a][b]
 
proc equiv*(a, b: Trit): Trit =
const t: array[Trit, array[Trit, Trit]] =
[ [ttrue, tmaybe, tfalse]
, [tmaybe, tmaybe, tmaybe]
, [tfalse, tmaybe, ttrue] ]
t[a][b]
 
 
when isMainModule:
 
import strutils
 
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)</syntaxhighlight>
{{out}}
<pre>Not T: F
Not ?: ?
Not F: T
T and T: T
T or T: T
T then T: T
T equiv T: T
T and ?: ?
T or ?: T
T then ?: ?
T equiv ?: ?
T and F: F
T or F: T
T then F: F
T equiv F: F
? and T: ?
? or T: T
? then T: T
? equiv T: ?
? and ?: ?
? or ?: ?
? then ?: ?
? equiv ?: ?
? and F: F
? or F: ?
? then F: ?
? equiv F: ?
F and T: F
F or T: T
F then T: T
F equiv T: F
F and ?: F
F or ?: ?
F then ?: T
F equiv ?: ?
F and F: F
F or F: F
F then F: T
F equiv F: T</pre>
 
=={{header|OCaml}}==
 
<langsyntaxhighlight lang="ocaml">type trit = True | False | Maybe
 
let t_not = function
Line 2,053 ⟶ 4,164:
print t_imply "Then";
print t_eq "Equiv";
;;</langsyntaxhighlight>
 
Output:
 
{{out}}
<pre>
Not True: False
Line 2,104 ⟶ 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 2,143 ⟶ 4,253:
table2 "or" t_or;;
table2 "equiv" t_equiv;;
table2 "implies" t_imply;;</langsyntaxhighlight>
{{out}}
Output:
<pre>
not:
Line 2,196 ⟶ 4,306:
 
=={{header|ooRexx}}==
<syntaxhighlight lang="oorexx">
<lang ooRexx>
tritValues = .array~of(.trit~true, .trit~false, .trit~maybe)
tab = '09'x
Line 2,321 ⟶ 4,431:
else if self == .trit~maybe then return .trit~maybe
else return \other
</syntaxhighlight>
</lang>
 
<pre>
Line 2,375 ⟶ 4,485:
 
=={{header|Pascal}}==
<langsyntaxhighlight lang="pascal">Program TernaryLogic (output);
 
type
Line 2,465 ⟶ 4,575:
writeln('False ', terToStr(terEquals(terTrue,terFalse)), ' ', terToStr(terEquals(terMayBe,terFalse)), ' ', terToStr(terEquals(terFalse,terFalse)));
writeln;
end.</langsyntaxhighlight>
{{out}}
Output:
<pre>
:> ./TernaryLogic
Line 2,497 ⟶ 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>
Output:
<pre>a NOT a
true false
maybe maybe
Line 2,637 ⟶ 4,715:
maybe 1
false 1</pre>
=={{header|Perl 6}}==
{{works with|niecza}}
Implementation:
<lang perl6>enum Trit <Foo Moo Too>;
 
=={{header|Phix}}==
sub prefix:<¬> (Trit $a) { Trit(1-($a-1)) }
{{libheader|Phix/basics}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">enum</span> <span style="color: #000000;">T</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">M</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">F</span>
<span style="color: #008080;">type</span> <span style="color: #000000;">ternary</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">T</span><span style="color: #0000FF;">,</span><span style="color: #000000;">M</span><span style="color: #0000FF;">,</span><span style="color: #000000;">F</span><span style="color: #0000FF;">})</span> <span style="color: #008080;">end</span> <span style="color: #008080;">type</span>
<span style="color: #008080;">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>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<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>
<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>
<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>
<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>
<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>
<span style="color: #008080;">if</span> <span style="color: #000000;">unary</span> <span style="color: #008080;">then</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;">" | %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: #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>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</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>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<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>
<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>
<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>
<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>
not |
----+---
T | F
? | ?
F | T
 
and | T | ? | F
sub infix:<∧> is equiv(&infix:<*>) (Trit $a, Trit $b) { $a min $b }
----+---+---+---
sub infix:<∨> is equiv(&infix:<+>) (Trit $a, Trit $b) { $a max $b }
T | T | ? | F
? | ? | ? | F
F | F | F | F
 
or | T | ? | F
sub infix:<→> is equiv(&infix:<..>) (Trit $a, Trit $b) { ¬$a max $b }
----+---+---+---
sub infix:<≡> is equiv(&infix:<eq>) (Trit $a, Trit $b) { Trit(1 + ($a-1) * ($b-1)) }</lang>
T | T | T | T
The precedence of each operator is specified as equivalent to an existing operator. We've taken the liberty of using an arrow for implication, to avoid confusing it with <tt>⊃</tt>, (U+2283 SUPERSET OF).
? | T | ? | ?
F | T | ? | F
 
xor | T | ? | F
To test, we use this code:
----+---+---+---
<lang perl6>say '¬';
T | F | ? | T
say "Too {¬Too}";
? | ? | ? | ?
say "Moo {¬Moo}";
F | T | ? | F
say "Foo {¬Foo}";
 
imp | T | ? | F
----+---+---+---
T | T | ? | F
? | T | ? | ?
F | T | T | T
 
eq | T | ? | F
sub tbl (&op,$name) {
----+---+---+---
say '';
T | T | ? | F
say "$name Too Moo Foo";
? | ? | ? | ?
say " ╔═══════════";
F | F | ? | T
say "Too║{op Too,Too} {op Too,Moo} {op Too,Foo}";
</pre>
say "Moo║{op Moo,Too} {op Moo,Moo} {op Moo,Foo}";
 
say "Foo║{op Foo,Too} {op Foo,Moo} {op Foo,Foo}";
=={{header|PHP}}==
Save the sample code as executable shell script on your *nix system:
<syntaxhighlight lang="php">#!/usr/bin/php
<?php
 
# defined as numbers, so I can use max() and min() on it
if (! define('triFalse',0)) trigger_error('Unknown error defining!', E_USER_ERROR);
if (! define('triMaybe',1)) trigger_error('Unknown error defining!', E_USER_ERROR);
if (! define('triTrue', 2)) trigger_error('Unknown error defining!', E_USER_ERROR);
 
$triNotarray = array(triFalse=>triTrue, triMaybe=>triMaybe, triTrue=>triFalse);
 
# output helper
function triString ($tri) {
if ($tri===triFalse) return 'false ';
if ($tri===triMaybe) return 'unknown';
if ($tri===triTrue) return 'true ';
trigger_error('triString: parameter not a tri value', E_USER_ERROR);
}
 
function triAnd() {
tbl(&infix:<∧>, '∧');
if (func_num_args() < 2)
tbl(&infix:<∨>, '∨');
trigger_error('triAnd needs 2 or more parameters', E_USER_ERROR);
tbl(&infix:<→>, '→');
return min(func_get_args());
tbl(&infix:<≡>, '≡');
}
 
function triOr() {
say '';
if (func_num_args() < 2)
say 'Precedence tests should all print "Too":';
trigger_error('triOr needs 2 or more parameters', E_USER_ERROR);
say ~(
return max(func_get_args());
Foo ∧ Too ∨ Too ≡ Too,
}
Foo ∧ (Too ∨ Too) ≡ Foo,
Too ∨ Too ∧ Foo ≡ Too,
(Too ∨ Too) ∧ Foo ≡ Foo,
 
function triNot($t) {
¬Too ∧ Too ∨ Too ≡ Too,
global $triNotarray; # using result table
¬Too ∧ (Too ∨ Too) ≡ ¬Too,
if (in_array($t, $triNotarray)) return $triNotarray[$t];
Too ∨ Too ∧ ¬Too ≡ Too,
trigger_error('triNot: Parameter is not a tri value', E_USER_ERROR);
(Too ∨ Too) ∧ ¬Too ≡ ¬Too,
}
Foo ∧ Too ∨ Foo → Foo ≡ Too,
Foo ∧ Too ∨ Too → Foo ≡ Foo,
);</lang>
Output:
<pre>¬
Too Foo
Moo Moo
Foo Too
 
function triImplies($a, $b) {
∧ Too Moo Foo
if ($a===triFalse || $b===triTrue) return triTrue;
╔═══════════
if ($a===triMaybe || $b===triMaybe) return triMaybe;
Too║Too Moo Foo
# without parameter type check I just would return triFalse here
Moo║Moo Moo Foo
if ($a===triTrue && $b===triFalse) return triFalse;
Foo║Foo Foo Foo
trigger_error('triImplies: parameter type error', E_USER_ERROR);
}
 
function triEquiv($a, $b) {
∨ Too Moo Foo
if ($a===triTrue) return $b;
╔═══════════
if ($a===triMaybe) return $a;
Too║Too Too Too
if ($a===triFalse) return triNot($b);
Moo║Too Moo Moo
trigger_error('triEquiv: parameter type error', E_USER_ERROR);
Foo║Too Moo Foo
}
 
# data sampling
→ Too Moo Foo
╔═══════════
Too║Too Moo Foo
Moo║Too Moo Moo
Foo║Too Too Too
 
printf("--- Sample output for a equivalent b ---\n\n");
≡ Too Moo Foo
╔═══════════
Too║Too Moo Foo
Moo║Moo Moo Moo
Foo║Foo Moo Too
 
foreach ([triTrue,triMaybe,triFalse] as $a) {
Precedence tests should all print "Too":
foreach ([triTrue,triMaybe,triFalse] as $b) {
Too Too Too Too Too Too Too Too Too Too</pre>
printf("for a=%s and b=%s a equivalent b is %s\n",
triString($a), triString($b), triString(triEquiv($a, $b)));
}
}
 
</syntaxhighlight>
Sample output:
<pre>--- Sample output for a equivalent b ---
 
for a=true and b=true a equivalent b is true
for a=true and b=unknown a equivalent b is unknown
for a=true and b=false a equivalent b is false
for a=unknown and b=true a equivalent b is unknown
for a=unknown and b=unknown a equivalent b is unknown
for a=unknown and b=false a equivalent b is unknown
for a=false and b=true a equivalent b is false
for a=false and b=unknown a equivalent b is unknown
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 2,746 ⟶ 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 2,754 ⟶ 5,027:
(for X '(T 0 NIL)
(for Y '(T 0 NIL)
(println X (car Fun) Y '-> ((cdr Fun) X Y)) ) ) )</langsyntaxhighlight>
{{out}}
Output:
<pre style="height:20em;overflow:scroll">not T -> NIL
not 0 -> 0
not NIL -> T
Line 2,795 ⟶ 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 2,926 ⟶ 5,268:
for b in values:
expr = '%s %s %s' % (a, op, b)
print(' %s = %s' % (expr, eval(expr)))</langsyntaxhighlight>
 
{{out}}
;Output:
<pre>
Trit logical inverse, '~'
Line 2,976 ⟶ 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
 
; weto can'tavoid addthe ahassle maybeof whichadding isa specialmaybe invalue thethat same wayis as #tspecial and #f,as
; sothe two standard booleans, we'll just use symbols to make our own
(define-type trit (U 'true 'false 'maybe))
 
Line 3,039 ⟶ 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}}
Output:
<pre>not true = false
not maybe = maybe
Line 3,083 ⟶ 5,563:
</pre>
 
=={{header|REXXRaku}}==
(formerly Perl 6)
This REXX program is a re-worked version of the REXX program used for ''truth table''.
{{Works with|rakudo|2018.03}}
<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*/
/*variables (propositional constants) allowed: A──►Z, a──►z except u. */
/*All propositional constants are case insensative (except lowercase v).*/
 
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).
parse arg expression /*get expression from the C. L. */
if expression\='' then do /*Got one? Then show user's stuff*/
call truthTable expression /*show and tell T.T.*/
exit /*we're all done with truth table*/
end
 
<syntaxhighlight lang="raku" line># Implementation:
call truthTable "a & b ; AND"
enum Trit <Foo Moo Too>;
call truthTable "a | b ; OR"
call truthTable "a ^ b ; XOR"
call truthTable "a ! b ; NOR"
call truthTable "a ¡ b ; NAND"
call truthTable "a xnor b ; XNOR" /*XNOR is the same as NXOR. */
exit /*stick a fork in it, we're done.*/
/*─────────────────────────────────────truthTable subroutine────────────*/
truthTable: procedure; parse arg $ ';' comm 1 $o; $o=strip($o)
$=translate(strip($),'|',"v"); $u=$; upper $u
$u=translate($u,'()()()',"[]{}«»"); $$.=0; PCs=; hdrPCs=
@abc='abcdefghijklmnopqrstuvwxyz'; @abcU=@abc; upper @abcU
 
sub prefix:<¬> (Trit $a) { Trit(1-($a-1)) }
@='ff'x /*─────────infix operators───────*/
op.= /*a single quote (') wasn't */
/* implemented for negation. */
op.0 ='false boolFALSE' /*unconditionally FALSE */
op.1 ='and and & *' /* AND, conjunction */
op.2 ='naimpb NaIMPb' /*not A implies B */
op.3 ='boolb boolB' /*B (value of) */
op.4 ='nbimpa NbIMPa' /*not B implies A */
op.5 ='boola boolA' /*A (value of) */
op.6 ='xor xor && % ^' /* XOR, exclusive OR */
op.7 ='or or | + v' /* OR, disjunction */
op.8 ='nor nor ! ↓' /* NOR, not OR, Pierce operator */
op.9 ='xnor xnor nxor' /*NXOR, not exclusive OR, not XOR*/
op.10='notb notB' /*not B (value of) */
op.11='bimpa bIMPa' /* B implies A */
op.12='nota notA' /*not A (value of) */
op.13='aimpb aIMPb' /* A implies B */
op.14='nand nand ¡ ↑' /*NAND, not AND, Sheffer operator*/
op.15='true boolTRUE' /*unconditionally TRUE */
/*alphabetic names need changing.*/
op.16='\ NOT ~ ─ . ¬' /* NOT, negation */
op.17='> GT' /*conditional */
op.18='>= GE ─> => ──> ==>' "1a"x /*conditional */
op.19='< LT' /*conditional */
op.20='<= LE <─ <= <── <==' /*conditional */
op.21='\= NE ~= ─= .= ¬=' /*conditional */
op.22='= EQ EQUAL EQUALS =' "1b"x /*biconditional */
op.23='0 boolTRUE' /*TRUEness */
op.24='1 boolFALSE' /*FALSEness */
 
sub infix:<∧> (Trit $a, Trit $b) is equiv(&infix:<*>) { $a min $b }
op.25='NOT NOT NEG' /*not, neg */
sub infix:<∨> (Trit $a, Trit $b) is equiv(&infix:<+>) { $a max $b }
 
sub infix:<⇒> (Trit $a, Trit $b) is equiv(&infix:<..>) { ¬$a max $b }
do jj=0 while op.jj\=='' | jj<16 /*change opers──►what REXX likes.*/
sub infix:<≡> (Trit $a, Trit $b) is equiv(&infix:<eq>) { Trit(1 + ($a-1) * ($b-1)) }
new=word(op.jj,1)
do kk=2 to words(op.jj) /*handle each token separately. */
_=word(op.jj,kk); upper _
if wordpos(_,$u)==0 then iterate /*no such animal in this string. */
if datatype(new,'m') then new!=@ /*expresion needs transcribing. */
else new!=new
$u=changestr(_,$u,new!) /*transcribe the function (maybe)*/
if new!==@ then $u=changeFunc($u,@,new) /*use internal bool name.*/
end /*kk*/
end /*jj*/
 
# Testing:
$u=translate($u, '()', "{}") /*finish cleaning up transcribing*/
say '¬';
do jj=1 for length(@abcU) /*see what variables are used. */
say "Too {¬Too}";
_=substr(@abcU,jj,1) /*use available upercase alphabet*/
say "Moo {¬Moo}";
if pos(_,$u)==0 then iterate /*found one? No, keep looking. */
say "Foo {¬Foo}";
$$.jj=2 /*found: set upper bound for it.*/
PCs=PCs _ /*also, add to propositional cons*/
hdrPCs=hdrPCS center(_,length('false')) /*build a PC header.*/
end /*jj*/
$u=PCs '('$u")" /*separate PCs from expression. */
ptr='_────►_' /*a pointer for the truth table. */
hdrPCs=substr(hdrPCs,2) /*create a header for the PCs. */
say hdrPCs left('',length(ptr)-1) $o /*display PC header + expression.*/
say copies('───── ',words(PCs)) left('',length(ptr)-2) copies('─',length($o))
/*Note: "true"s: right─justified*/
do a=0 to $$.1
do b=0 to $$.2
do c=0 to $$.3
do d=0 to $$.4
do e=0 to $$.5
do f=0 to $$.6
do g=0 to $$.7
do h=0 to $$.8
do i=0 to $$.9
do j=0 to $$.10
do k=0 to $$.11
do l=0 to $$.12
do m=0 to $$.13
do n=0 to $$.14
do o=0 to $$.15
do p=0 to $$.16
do q=0 to $$.17
do r=0 to $$.18
do s=0 to $$.19
do t=0 to $$.20
do u=0 to $$.21
do !=0 to $$.22
do w=0 to $$.23
do x=0 to $$.24
do y=0 to $$.25
do z=0 to $$.26
interpret '_=' $u /*evaluate truth T.*/
_=changestr(0,_,'false') /*convert 0──►false*/
_=changestr(1,_,'_true') /*convert 1──►_true*/
_=changestr(2,_,'maybe') /*convert 2──►maybe*/
_=insert(ptr,_,wordindex(_,words(_))-1) /*──►*/
say translate(_,,'_') /*display truth tab*/
end /*z*/
end /*y*/
end /*x*/
end /*w*/
end /*v*/
end /*u*/
end /*t*/
end /*s*/
end /*r*/
end /*q*/
end /*p*/
end /*o*/
end /*n*/
end /*m*/
end /*l*/
end /*k*/
end /*j*/
end /*i*/
end /*h*/
end /*g*/
end /*f*/
end /*e*/
end /*d*/
end /*c*/
end /*b*/
end /*a*/
 
sub tbl (&op,$name) {
say; return
say '';
/*─────────────────────────────────────SCAN subroutine──────────────────*/
say "$name Too Moo Foo";
scan: procedure; parse arg x,at; L=length(x); t=L; lp=0; apost=0; quote=0
say " ╔═══════════";
if at<0 then do; t=1; x=translate(x,'()',")("); end
say "Too║{op Too,Too} {op Too,Moo} {op Too,Foo}";
do j=abs(at) to t by sign(at); _=substr(x,j,1); __=substr(x,j,2)
say "Moo║{op Moo,Too} {op Moo,Moo} {op Moo,Foo}";
if quote then do; if _\=='"' then iterate
say "Foo║{op Foo,Too} {op Foo,Moo} {op Foo,Foo}";
if __=='""' then do; j=j+1; iterate; end
}
quote=0; iterate
 
end
tbl(&infix:<∧>, '∧');
if apost then do; if _\=="'" then iterate
tbl(&infix:<∨>, '∨');
if __=="''" then do; j=j+1; iterate; end
tbl(&infix:<⇒>, '⇒');
apost=0; iterate
tbl(&infix:<≡>, '≡');
end
 
if _=='"' then do; quote=1; iterate; end
say '';
if _=="'" then do; apost=1; iterate; end
say 'Precedence tests should all print "Too":';
if _==' ' then iterate
say ~(
if _=='(' then do; lp=lp+1; iterate; end
Foo ∧ Too ∨ Too ≡ Too,
if lp\==0 then do; if _==')' then lp=lp-1; iterate; end
Foo ∧ (Too ∨ Too) ≡ Foo,
if datatype(_,'U') then return j-(at<0)
Too ∨ Too ∧ Foo ≡ Too,
if at<0 then return j+1
(Too endToo) Foo /*j*/≡ Foo,
 
return min(j,L)
¬Too ∧ Too ∨ Too ≡ Too,
/*─────────────────────────────────────changeFunc subroutine────────────*/
¬Too ∧ (Too ∨ Too) ≡ ¬Too,
changeFunc: procedure; parse arg z,fC,newF; funcPos=0
Too Too ¬Too do foreverToo,
(Too ∨ Too) ∧ ¬Too ≡ ¬Too,
funcPos=pos(fC,z,funcPos+1); if funcPos==0 then return z
origPos=funcPos
Foo ∧ Too ∨ Foo ⇒ Foo ≡ Too,
z=changestr(fC,z,",'"newF"',")
Foo ∧ Too ∨ Too ⇒ Foo ≡ Foo,
funcPos=funcPos+length(newF)+4
);</syntaxhighlight>
where=scan(z, funcPos) ; z=insert( '}', z, where)
 
where=scan(z, 1-origPos) ; z=insert('trit{', z, where)
{{out}}
end /*forever*/
<pre>¬
/*─────────────────────────────────────TRIT subroutine──────────────────*/
Too Foo
trit: procedure; arg a,$,b; v=\(a==2|b==2); o= a==1|b==1; z= a==0|b==0
Moo Moo
select
Foo Too
when $=='FALSE' then return 0
 
when $=='AND' then if v then return a & b; else return 2
∧ Too Moo Foo
when $=='NAIMPB' then if v then return \(\a & \b); else return 2
╔═══════════
when $=='BOOLB' then return b
Too║Too Moo Foo
when $=='NBIMPA' then if v then return \(\b & \a); else return 2
Moo║Moo Moo Foo
when $=='BOOLA' then return a
Foo║Foo Foo Foo
when $=='XOR' then if v then return a && b ; else return 2
 
when $=='OR' then if v then return a | b ; else
∨ Too Moo Foo
if o then return 1; else return 2
╔═══════════
when $=='NOR' then if v then return \(a | b) ; else return 2
Too║Too Too Too
when $=='XNOR' then if v then return \(a && b) ; else return 2
Moo║Too Moo Moo
when $=='NOTB' then if v then return \b ; else return 2
Foo║Too Moo Foo
when $=='NOTA' then if v then return \a ; else return 2
 
when $=='AIMPB' then if v then return \(a & \b) ; else return 2
⇒ Too Moo Foo
when $=='NAND' then if v then return \(a & b) ; else
╔═══════════
if z then return 1; else return 2
Too║Too Moo Foo
when $=='TRUE' then return 1
Moo║Too Moo Moo
otherwise return -13 /*error, unknown function.*/
Foo║Too Too Too
end /*select*/</lang>
 
Some older REXXes don't have a &nbsp; '''changestr''' &nbsp; BIF, so one is included here ──► [[CHANGESTR.REX]].
≡ 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''.
<syntaxhighlight 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. */
/*──── Variables (propositional constants) allowed: A ──► Z, a ──► z except u.*/
/*──── All propositional constants are case insensative (except lowercase v). */
parse arg $express /*obtain optional argument from the CL.*/
if $express\='' then do /*Got one? Then show user's expression*/
call truthTable $express /*display the user's truth table──►term*/
exit /*we're all done with the truth table. */
end
 
call truthTable "a & b ; AND"
call truthTable "a | b ; OR"
call truthTable "a ^ b ; XOR"
call truthTable "a ! b ; NOR"
call truthTable "a ¡ b ; NAND"
call truthTable "a xnor b ; XNOR" /*XNOR is the same as NXOR. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
truthTable: procedure; parse arg $ ';' comm 1 $o; $o=strip($o)
$=translate(strip($), '|', "v"); $u=$; upper $u
$u=translate($u, '()()()', "[]{}«»"); $$.=0; PCs=; hdrPCs=
@abc= 'abcdefghijklmnopqrstuvwxyz'; @abcU=@abc; upper @abcU
@= 'ff'x /*─────────infix operators───────*/
op.= /*a single quote (') wasn't */
/* implemented for negation. */
op.0 = 'false boolFALSE' /*unconditionally FALSE */
op.1 = 'and and & *' /* AND, conjunction */
op.2 = 'naimpb NaIMPb' /*not A implies B */
op.3 = 'boolb boolB' /*B (value of) */
op.4 = 'nbimpa NbIMPa' /*not B implies A */
op.5 = 'boola boolA' /*A (value of) */
op.6 = 'xor xor && % ^' /* XOR, exclusive OR */
op.7 = 'or or | + v' /* OR, disjunction */
op.8 = 'nor nor ! ↓' /* NOR, not OR, Pierce operator */
op.9 = 'xnor xnor nxor' /*NXOR, not exclusive OR, not XOR*/
op.10 = 'notb notB' /*not B (value of) */
op.11 = 'bimpa bIMPa' /* B implies A */
op.12 = 'nota notA' /*not A (value of) */
op.13 = 'aimpb aIMPb' /* A implies B */
op.14 = 'nand nand ¡ ↑' /*NAND, not AND, Sheffer operator*/
op.15 = 'true boolTRUE' /*unconditionally TRUE */
/*alphabetic names need changing.*/
op.16 = '\ NOT ~ ─ . ¬' /* NOT, negation */
op.17 = '> GT' /*conditional greater than */
op.18 = '>= GE ─> => ──> ==>' "1a"x /*conditional greater than or eq.*/
op.19 = '< LT' /*conditional less than */
op.20 = '<= LE <─ <= <── <==' /*conditional less then or equal */
op.21 = '\= NE ~= ─= .= ¬=' /*conditional not equal to */
op.22 = '= EQ EQUAL EQUALS =' "1b"x /*biconditional (equals) */
op.23 = '0 boolTRUE' /*TRUEness */
op.24 = '1 boolFALSE' /*FALSEness */
 
op.25 = 'NOT NOT NEG' /*not, neg (negative) */
 
do jj=0 while op.jj\=='' | jj<16 /*change opers──►what REXX likes.*/
new=word(op.jj,1)
do kk=2 to words(op.jj) /*handle each token separately. */
_=word(op.jj, kk); upper _
if wordpos(_, $u)==0 then iterate /*no such animal in this string. */
if datatype(new, 'm') then new!=@ /*expresion needs transcribing. */
else new!=new
$u=changestr(_, $u, new!) /*transcribe the function (maybe)*/
if new!==@ then $u=changeFunc($u, @, new) /*use the internal boolean name. */
end /*kk*/
end /*jj*/
 
$u=translate($u, '()', "{}") /*finish cleaning up transcribing*/
do jj=1 for length(@abcU) /*see what variables are used. */
_=substr(@abcU, jj, 1) /*use available upercase alphabet*/
if pos(_,$u)==0 then iterate /*found one? No, keep looking. */
$$.jj=2 /*found: set upper bound for it.*/
PCs=PCs _ /*also, add to propositional cons*/
hdrPCs=hdrPCS center(_, length('false')) /*build a propositional cons hdr.*/
end /*jj*/
$u=PCs '('$u")" /*sep prop. cons. from expression*/
ptr='_────►_' /*a pointer for the truth table. */
hdrPCs=substr(hdrPCs,2) /*create a header for prop. cons.*/
say hdrPCs left('', length(ptr) -1) $o /*show prop cons hdr +expression.*/
say copies('───── ', words(PCs)) left('', length(ptr)-2) copies('─', length($o))
/*Note: "true"s: right─justified*/
do a=0 to $$.1
do b=0 to $$.2
do c=0 to $$.3
do d=0 to $$.4
do e=0 to $$.5
do f=0 to $$.6
do g=0 to $$.7
do h=0 to $$.8
do i=0 to $$.9
do j=0 to $$.10
do k=0 to $$.11
do l=0 to $$.12
do m=0 to $$.13
do n=0 to $$.14
do o=0 to $$.15
do p=0 to $$.16
do q=0 to $$.17
do r=0 to $$.18
do s=0 to $$.19
do t=0 to $$.20
do u=0 to $$.21
do !=0 to $$.22
do w=0 to $$.23
do x=0 to $$.24
do y=0 to $$.25
do z=0 to $$.26
interpret '_=' $u /*evaluate truth T.*/
_=changestr(0, _, 'false') /*convert 0──►false*/
_=changestr(1, _, '_true') /*convert 1──►_true*/
_=changestr(2, _, 'maybe') /*convert 2──►maybe*/
_=insert(ptr, _, wordindex(_, words(_)) -1) /*──►*/
say translate(_, , '_') /*display truth tab*/
end /*z*/
end /*y*/
end /*x*/
end /*w*/
end /*v*/
end /*u*/
end /*t*/
end /*s*/
end /*r*/
end /*q*/
end /*p*/
end /*o*/
end /*n*/
end /*m*/
end /*l*/
end /*k*/
end /*j*/
end /*i*/
end /*h*/
end /*g*/
end /*f*/
end /*e*/
end /*d*/
end /*c*/
end /*b*/
end /*a*/
say
return
/*──────────────────────────────────────────────────────────────────────────────────────*/
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)
if quote then do; if _\=='"' then iterate
if __=='""' then do; j=j+1; iterate; end
quote=0; iterate
end
if apost then do; if _\=="'" then iterate
if __=="''" then do; j=j+1; iterate; end
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
end /*j*/
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*/
</syntaxhighlight>
Some older REXXes don't have a &nbsp; '''changestr''' &nbsp; BIF, so one is included here &nbsp; ──► &nbsp; [[CHANGESTR.REX]].
<br><br>
'''output'''
<pre>
<pre style="overflow:scroll">
A B a & b ; AND
───── ───── ───────────
Line 3,357 ⟶ 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 3,364 ⟶ 6,017:
 
{{works with|Ruby|1.9}}
<langsyntaxhighlight lang="ruby"># trit.rb - ternary logic
# http://rosettacode.org/wiki/Ternary_logic
 
Line 3,448 ⟶ 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 3,468 ⟶ 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 3,479 ⟶ 6,132:
printf "%5s ^ %5s => %5s\n", a, b, a.trit ^ b
end
end</langsyntaxhighlight>
 
<pre>$ ruby -I. trit-xor.rb
Line 3,493 ⟶ 6,146:
 
=={{header|Run BASIC}}==
<langsyntaxhighlight lang="runbasic">testFalse = 0 ' F
testDoNotKnow = 1 ' ?
testTrue = 2 ' T
Line 3,550 ⟶ 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 3,564 ⟶ 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 3,597 ⟶ 6,391:
println("\n- Equiv -")
for(a<-v; b<-v) println("%6s : %6s => %6s".format(a, b, a equiv b))
}</langsyntaxhighlight>
{{out}}
Output:
<pre>- NOT -
TTrue => TFalse
Line 3,667 ⟶ 6,461:
which use also short circuit evaluation.
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const type: trit is new enum
Line 3,734 ⟶ 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 3,741 ⟶ 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)));
 
const func integer: compare (in trit: aTrit1, in trit: aTrit2) is
return compare(ord(aTrit1), ord(aTrit2));
 
const func integer: hashCode (in trit: aTrit) is
return hashCode(ord(aTrit));
 
# Begin of test code
Line 3,786 ⟶ 6,572:
writeTable(operand1 -> operand2, "->");
writeTable(operand1 == operand2, "==");
end func;</langsyntaxhighlight>
 
{{out}}
Output:
<pre>
not | False Maybe True
Line 3,824 ⟶ 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 3,893 ⟶ 6,797:
* false
}
}</langsyntaxhighlight>
Demonstrating:
<langsyntaxhighlight lang="tcl">namespace import ternary::*
puts "x /\\ y == x \\/ y"
puts " x | y || result"
Line 3,904 ⟶ 6,808:
puts [format " %-5s | %-5s || %-5s" $x $y $z]
}
}</langsyntaxhighlight>
{{out}}
Output:
<pre>
x /\ y == x \/ y
Line 3,919 ⟶ 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