Ternary logic: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
|||
Line 95: | Line 95: | ||
=={{header|Action!}}== |
=={{header|Action!}}== |
||
< |
<syntaxhighlight lang="action!">DEFINE TERNARY="BYTE" |
||
DEFINE FALSE="0" |
DEFINE FALSE="0" |
||
DEFINE MAYBE="1" |
DEFINE MAYBE="1" |
||
Line 192: | Line 192: | ||
OD |
OD |
||
OD |
OD |
||
RETURN</ |
RETURN</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Ternary_logic.png Screenshot from Atari 8-bit computer] |
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Ternary_logic.png Screenshot from Atari 8-bit computer] |
||
Line 224: | Line 224: | ||
We first specify a package "Logic" for three-valued logic. Observe that predefined Boolean functions, "and" "or" and "not" are overloaded: |
We first specify a package "Logic" for three-valued logic. Observe that predefined Boolean functions, "and" "or" and "not" are overloaded: |
||
< |
<syntaxhighlight lang="ada">package Logic is |
||
type Ternary is (True, Unknown, False); |
type Ternary is (True, Unknown, False); |
||
Line 238: | Line 238: | ||
function To_Ternary(B: Boolean) return Ternary; |
function To_Ternary(B: Boolean) return Ternary; |
||
function Image(Value: Ternary) return Character; |
function Image(Value: Ternary) return Character; |
||
end Logic;</ |
end Logic;</syntaxhighlight> |
||
Next, the implementation of the package: |
Next, the implementation of the package: |
||
< |
<syntaxhighlight lang="ada">package body Logic is |
||
-- type Ternary is (True, Unknown, False); |
-- type Ternary is (True, Unknown, False); |
||
Line 303: | Line 303: | ||
end Implies; |
end Implies; |
||
end Logic;</ |
end Logic;</syntaxhighlight> |
||
Finally, a sample program: |
Finally, a sample program: |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO, Logic; |
||
procedure Test_Tri_Logic is |
procedure Test_Tri_Logic is |
||
Line 340: | Line 340: | ||
Truth_Table(F => Equivalent'Access, Name => "Eq"); |
Truth_Table(F => Equivalent'Access, Name => "Eq"); |
||
Truth_Table(F => Implies'Access, Name => "Implies"); |
Truth_Table(F => Implies'Access, Name => "Implies"); |
||
end Test_Tri_Logic;</ |
end Test_Tri_Logic;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 366: | Line 366: | ||
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}} |
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}} |
||
'''File: Ternary_logic.a68''' |
'''File: Ternary_logic.a68''' |
||
< |
<syntaxhighlight lang="algol68"># -*- coding: utf-8 -*- # |
||
INT trit width = 1, trit base = 3; |
INT trit width = 1, trit base = 3; |
||
Line 464: | Line 464: | ||
#true # (false, maybe, true ) |
#true # (false, maybe, true ) |
||
)[@-1,@-1][INITINT a, INITINT b] |
)[@-1,@-1][INITINT a, INITINT b] |
||
);</ |
);</syntaxhighlight>'''File: Template_operators_logical_mixin.a68''' |
||
< |
<syntaxhighlight lang="algol68"># -*- coding: utf-8 -*- # |
||
OP & = (LOGICAL a,b)LOGICAL: a AND b; |
OP & = (LOGICAL a,b)LOGICAL: a AND b; |
||
Line 489: | Line 489: | ||
OP ~ = (LOGICAL a)LOGICAL: NOT a, |
OP ~ = (LOGICAL a)LOGICAL: NOT a, |
||
~= = (LOGICAL a,b)LOGICAL: a /= b; SCALAR! |
~= = (LOGICAL a,b)LOGICAL: a /= b; SCALAR! |
||
FI#</ |
FI#</syntaxhighlight>'''File: test_Ternary_logic.a68''' |
||
< |
<syntaxhighlight lang="algol68">#!/usr/local/bin/a68g --script # |
||
# -*- coding: utf-8 -*- # |
# -*- coding: utf-8 -*- # |
||
Line 559: | Line 559: | ||
print trit op table("⊃","IMPLIES", (TRIT a,b)TRIT: a IMPLIES b); |
print trit op table("⊃","IMPLIES", (TRIT a,b)TRIT: a IMPLIES b); |
||
print trit op table("∧","AND", (TRIT a,b)TRIT: a AND b); |
print trit op table("∧","AND", (TRIT a,b)TRIT: a AND b); |
||
print trit op table("∨","OR", (TRIT a,b)TRIT: a OR b)</ |
print trit op table("∨","OR", (TRIT a,b)TRIT: a OR b)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 622: | Line 622: | ||
Arturo's '':logical'' values inherently support ternary logic (<code>true</code>, <code>false</code> and <code>maybe</code>) and the corresponding logical operations. |
Arturo's '':logical'' values inherently support ternary logic (<code>true</code>, <code>false</code> and <code>maybe</code>) and the corresponding logical operations. |
||
< |
<syntaxhighlight lang="rebol">vals: @[true maybe false] |
||
loop vals 'v -> print ["NOT" v "=>" not? v] |
loop vals 'v -> print ["NOT" v "=>" not? v] |
||
Line 639: | Line 639: | ||
loop vals 'v2 |
loop vals 'v2 |
||
-> print [v1 "XOR" v2 "=>" xor? v1 v2] |
-> print [v1 "XOR" v2 "=>" xor? v1 v2] |
||
]</ |
]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 679: | Line 679: | ||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
< |
<syntaxhighlight lang="autohotkey">Ternary_Not(a){ |
||
SetFormat, Float, 2.1 |
SetFormat, Float, 2.1 |
||
return Abs(a-1) |
return Abs(a-1) |
||
Line 698: | Line 698: | ||
Ternary_Equiv(a,b){ |
Ternary_Equiv(a,b){ |
||
return a=b?1:a=1?b:b=1?a:0.5 |
return a=b?1:a=1?b:b=1?a:0.5 |
||
}</ |
}</syntaxhighlight> |
||
Examples:< |
Examples:<syntaxhighlight lang="autohotkey">aa:=[1,0.5,0] |
||
bb:=[1,0.5,0] |
bb:=[1,0.5,0] |
||
Line 729: | Line 729: | ||
StringReplace, Res, Res, 0, false, all |
StringReplace, Res, Res, 0, false, all |
||
MsgBox % Res |
MsgBox % Res |
||
return</ |
return</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> Ternary_Not true = false |
<pre> Ternary_Not true = false |
||
Line 778: | Line 778: | ||
=={{header|BASIC256}}== |
=={{header|BASIC256}}== |
||
{{trans|Liberty BASIC}} |
{{trans|Liberty BASIC}} |
||
<syntaxhighlight lang="lb"> |
|||
<lang lb> |
|||
global tFalse, tDontKnow, tTrue |
global tFalse, tDontKnow, tTrue |
||
tFalse = 0 |
tFalse = 0 |
||
Line 849: | Line 849: | ||
end case |
end case |
||
end function |
end function |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 857: | Line 857: | ||
=={{header|BBC BASIC}}== |
=={{header|BBC BASIC}}== |
||
{{works with|BBC BASIC for Windows}} |
{{works with|BBC BASIC for Windows}} |
||
< |
<syntaxhighlight lang="bbcbasic"> INSTALL @lib$ + "CLASSLIB" |
||
REM Create a ternary class: |
REM Create a ternary class: |
||
Line 902: | Line 902: | ||
PRINT "TRUE EQV TRUE = " FN(mytrit.teqv)("TRUE","TRUE") |
PRINT "TRUE EQV TRUE = " FN(mytrit.teqv)("TRUE","TRUE") |
||
PROC_discard(mytrit{})</ |
PROC_discard(mytrit{})</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 937: | Line 937: | ||
=={{header|C}}== |
=={{header|C}}== |
||
===Implementing logic using lookup tables=== |
===Implementing logic using lookup tables=== |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
typedef enum { |
typedef enum { |
||
Line 1,007: | Line 1,007: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,055: | Line 1,055: | ||
===Using functions=== |
===Using functions=== |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
typedef enum { t_F = -1, t_M, t_T } trit; |
typedef enum { t_F = -1, t_M, t_T } trit; |
||
Line 1,090: | Line 1,090: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>[Not] |
<pre>[Not] |
||
Line 1,131: | Line 1,131: | ||
the result is randomly sampled to true or false according to the chance. |
the result is randomly sampled to true or false according to the chance. |
||
(This description is definitely very confusing perhaps). |
(This description is definitely very confusing perhaps). |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
Line 1,185: | Line 1,185: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
/// <summary> |
/// <summary> |
||
Line 1,232: | Line 1,232: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>¬True = False |
<pre>¬True = False |
||
Line 1,276: | Line 1,276: | ||
=={{header|C++}}== |
=={{header|C++}}== |
||
Essentially the same logic as the [[#Using functions|Using functions]] implementation above, but using class-based encapsulation and overridden operators. |
Essentially the same logic as the [[#Using functions|Using functions]] implementation above, but using class-based encapsulation and overridden operators. |
||
< |
<syntaxhighlight lang="cpp">#include <iostream> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
Line 1,349: | Line 1,349: | ||
show_op(==); |
show_op(==); |
||
return EXIT_SUCCESS; |
return EXIT_SUCCESS; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>! ---- |
<pre>! ---- |
||
Line 1,381: | Line 1,381: | ||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
< |
<syntaxhighlight lang="lisp">(defun tri-not (x) (- 1 x)) |
||
(defun tri-and (&rest x) (apply #'* x)) |
(defun tri-and (&rest x) (apply #'* x)) |
||
(defun tri-or (&rest x) (tri-not (apply #'* (mapcar #'tri-not x)))) |
(defun tri-or (&rest x) (tri-not (apply #'* (mapcar #'tri-not x)))) |
||
Line 1,411: | Line 1,411: | ||
(print-table #'tri-or "OR") |
(print-table #'tri-or "OR") |
||
(print-table #'tri-imply "IMPLY") |
(print-table #'tri-imply "IMPLY") |
||
(print-table #'tri-eq "EQUAL")</ |
(print-table #'tri-eq "EQUAL")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>NOT: |
<pre>NOT: |
||
Line 1,448: | Line 1,448: | ||
=={{header|D}}== |
=={{header|D}}== |
||
Partial translation of a C entry: |
Partial translation of a C entry: |
||
< |
<syntaxhighlight lang="d">import std.stdio; |
||
struct Trit { |
struct Trit { |
||
Line 1,515: | Line 1,515: | ||
showOperation!"=="("Equiv"); |
showOperation!"=="("Equiv"); |
||
showOperation!"==>"("Imply"); |
showOperation!"==>"("Imply"); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>[Not] |
<pre>[Not] |
||
Line 1,558: | Line 1,558: | ||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
< |
<syntaxhighlight lang="delphi">unit TrinaryLogic; |
||
interface |
interface |
||
Line 1,613: | Line 1,613: | ||
end; |
end; |
||
end.</ |
end.</syntaxhighlight> |
||
And that's the reason why you never on no account ''ever'' should compare against the values of True or False unless you intent ternary logic! |
And that's the reason why you never on no account ''ever'' should compare against the values of True or False unless you intent ternary logic! |
||
An alternative version would be using an enum type |
An alternative version would be using an enum type |
||
< |
<syntaxhighlight lang="delphi">type TriBool = (tbFalse, tbMaybe, tbTrue);</syntaxhighlight> |
||
and defining a set of constants implementing the above tables: |
and defining a set of constants implementing the above tables: |
||
< |
<syntaxhighlight lang="delphi">const |
||
tvl_not: array[TriBool] = (tbTrue, tbMaybe, tbFalse); |
tvl_not: array[TriBool] = (tbTrue, tbMaybe, tbFalse); |
||
tvl_and: array[TriBool, TriBool] = ( |
tvl_and: array[TriBool, TriBool] = ( |
||
Line 1,642: | Line 1,642: | ||
(tbFalse, tbMaybe, tbTrue), |
(tbFalse, tbMaybe, tbTrue), |
||
); |
); |
||
</syntaxhighlight> |
|||
</lang> |
|||
That's no real fun, but lookup can then be done with |
That's no real fun, but lookup can then be done with |
||
< |
<syntaxhighlight lang="delphi">Result := tvl_and[A, B];</syntaxhighlight> |
||
=={{header|Elena}}== |
=={{header|Elena}}== |
||
ELENA 5.0 : |
ELENA 5.0 : |
||
< |
<syntaxhighlight lang="elena">import extensions; |
||
import system'routines; |
import system'routines; |
||
import system'collections; |
import system'collections; |
||
Line 1,717: | Line 1,717: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,762: | Line 1,762: | ||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
< |
<syntaxhighlight lang="erlang">% Implemented by Arjun Sunel |
||
-module(ternary). |
-module(ternary). |
||
-export([main/0, nott/1, andd/2,orr/2, then/2, equiv/2]). |
-export([main/0, nott/1, andd/2,orr/2, then/2, equiv/2]). |
||
Line 1,836: | Line 1,836: | ||
io: format("~s\n", [B]) |
io: format("~s\n", [B]) |
||
end. |
end. |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
For boolean logic, Factor uses ''t'' and ''f'' with the words ''>boolean'', ''not'', ''and'', ''or'', ''xor''. For ternary logic, we add ''m'' and define the words ''>trit'', ''tnot'', ''tand'', ''tor'', ''txor'' and ''t=''. Our new class, ''trit'', is the union class of ''t'', ''m'' and ''f''. |
For boolean logic, Factor uses ''t'' and ''f'' with the words ''>boolean'', ''not'', ''and'', ''or'', ''xor''. For ternary logic, we add ''m'' and define the words ''>trit'', ''tnot'', ''tand'', ''tor'', ''txor'' and ''t=''. Our new class, ''trit'', is the union class of ''t'', ''m'' and ''f''. |
||
< |
<syntaxhighlight lang="factor">! rosettacode/ternary/ternary.factor |
||
! http://rosettacode.org/wiki/Ternary_logic |
! http://rosettacode.org/wiki/Ternary_logic |
||
USING: combinators kernel ; |
USING: combinators kernel ; |
||
Line 1,881: | Line 1,881: | ||
{ m [ >trit drop m ] } |
{ m [ >trit drop m ] } |
||
{ f [ tnot ] } |
{ f [ tnot ] } |
||
} case ;</ |
} case ;</syntaxhighlight> |
||
Example use: |
Example use: |
||
< |
<syntaxhighlight lang="factor">( scratchpad ) CONSTANT: trits { t m f } |
||
( scratchpad ) trits [ tnot ] map . |
( scratchpad ) trits [ tnot ] map . |
||
{ f m t } |
{ f m t } |
||
Line 1,894: | Line 1,894: | ||
{ { f m t } { m m m } { t m f } } |
{ { f m t } { m m m } { t m f } } |
||
( scratchpad ) trits [ trits swap [ t= ] curry map ] map . |
( scratchpad ) trits [ trits swap [ t= ] curry map ] map . |
||
{ { t m f } { m m m } { f m t } }</ |
{ { t m f } { m m m } { f m t } }</syntaxhighlight> |
||
Line 1,902: | Line 1,902: | ||
Standard Forth defines flags 'false' as 0 and 'true' as -1 (all bits set). We thus define 'maybe' as 1 to keep standard binary logic as-is and seamlessly include ternary logic. We may have use truthtables but here functions are more fluid. |
Standard Forth defines flags 'false' as 0 and 'true' as -1 (all bits set). We thus define 'maybe' as 1 to keep standard binary logic as-is and seamlessly include ternary logic. We may have use truthtables but here functions are more fluid. |
||
< |
<syntaxhighlight lang="forth">1 constant maybe |
||
: tnot dup maybe <> if invert then ; |
: tnot dup maybe <> if invert then ; |
||
Line 1,935: | Line 1,935: | ||
CR ." [IMPLY]" ' timply table2. CR |
CR ." [IMPLY]" ' timply table2. CR |
||
CR ." [EQUIV]" ' tequiv table2. CR |
CR ." [EQUIV]" ' tequiv table2. CR |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 1,995: | Line 1,995: | ||
Please find the demonstration and compilation with gfortran at the start of the code. A module contains the ternary logic for easy reuse. Consider input redirection from unixdict.txt as vestigial. Or I could delete it. |
Please find the demonstration and compilation with gfortran at the start of the code. A module contains the ternary logic for easy reuse. Consider input redirection from unixdict.txt as vestigial. Or I could delete it. |
||
<syntaxhighlight lang="fortran"> |
|||
<lang FORTRAN> |
|||
!-*- mode: compilation; default-directory: "/tmp/" -*- |
!-*- mode: compilation; default-directory: "/tmp/" -*- |
||
!Compilation started at Mon May 20 23:05:46 |
!Compilation started at Mon May 20 23:05:46 |
||
Line 2,093: | Line 2,093: | ||
end program ternaryLogic |
end program ternaryLogic |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Free Pascal}}== |
=={{header|Free Pascal}}== |
||
Line 2,099: | Line 2,099: | ||
Note equivalence and implication are used as proof, they are solved using the basic set instead of a lookup. |
Note equivalence and implication are used as proof, they are solved using the basic set instead of a lookup. |
||
Note Since we use a balanced range -1,0,1 multiplication equals EQU |
Note Since we use a balanced range -1,0,1 multiplication equals EQU |
||
< |
<syntaxhighlight lang="pascal">{$mode objfpc} |
||
unit ternarylogic; |
unit ternarylogic; |
||
Line 2,165: | Line 2,165: | ||
end; |
end; |
||
end. |
end. |
||
</syntaxhighlight> |
|||
</lang> |
|||
< |
<syntaxhighlight lang="pascal">program ternarytests; |
||
{$mode objfpc} |
{$mode objfpc} |
||
uses |
uses |
||
Line 2,211: | Line 2,211: | ||
writeln('F|',tFalse >< tTrue:7, tFalse >< tMaybe:7,tFalse >< tFalse:7); |
writeln('F|',tFalse >< tTrue:7, tFalse >< tMaybe:7,tFalse >< tFalse:7); |
||
writeln; |
writeln; |
||
end.</ |
end.</syntaxhighlight> |
||
<pre> |
<pre> |
||
Output: |
Output: |
||
Line 2,251: | Line 2,251: | ||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
< |
<syntaxhighlight lang="freebasic">enum trit |
||
F=-1, M=0, T=1 |
F=-1, M=0, T=1 |
||
end enum |
end enum |
||
Line 2,295: | Line 2,295: | ||
outstr += " " + symbol(not(i)) |
outstr += " " + symbol(not(i)) |
||
print outstr |
print outstr |
||
next i</ |
next i</syntaxhighlight> |
||
<pre> |
<pre> |
||
(AND) ( OR) (EQV) (IMP) (NOT) |
(AND) ( OR) (EQV) (IMP) (NOT) |
||
Line 2,321: | Line 2,321: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
Go has four operators for the bool type: ==, &&, ||, and !. |
Go has four operators for the bool type: ==, &&, ||, and !. |
||
< |
<syntaxhighlight lang="go">package main |
||
import "fmt" |
import "fmt" |
||
Line 2,395: | Line 2,395: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,439: | Line 2,439: | ||
=={{header|Groovy}}== |
=={{header|Groovy}}== |
||
Solution: |
Solution: |
||
< |
<syntaxhighlight lang="groovy">enum Trit { |
||
TRUE, MAYBE, FALSE |
TRUE, MAYBE, FALSE |
||
Line 2,456: | Line 2,456: | ||
Trit imply(Trit that) { this.nand(that.not()) } |
Trit imply(Trit that) { this.nand(that.not()) } |
||
Trit equiv(Trit that) { this.and(that).or(this.nor(that)) } |
Trit equiv(Trit that) { this.and(that).or(this.nor(that)) } |
||
}</ |
}</syntaxhighlight> |
||
Test: |
Test: |
||
< |
<syntaxhighlight lang="groovy">printf 'AND\n ' |
||
Trit.values().each { b -> printf ('%6s', b) } |
Trit.values().each { b -> printf ('%6s', b) } |
||
println '\n ----- ----- -----' |
println '\n ----- ----- -----' |
||
Line 2,498: | Line 2,498: | ||
Trit.values().each { b -> printf ('%6s', a.equiv(b)) } |
Trit.values().each { b -> printf ('%6s', a.equiv(b)) } |
||
println() |
println() |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,538: | Line 2,538: | ||
All operations given in terms of NAND, the functionally-complete operation. |
All operations given in terms of NAND, the functionally-complete operation. |
||
< |
<syntaxhighlight lang="haskell">import Prelude hiding (Bool(..), not, (&&), (||), (==)) |
||
main = mapM_ (putStrLn . unlines . map unwords) |
main = mapM_ (putStrLn . unlines . map unwords) |
||
Line 2,574: | Line 2,574: | ||
where header = map (:[]) (take ((length $ head xs) - 1) ['A'..]) ++ [name] |
where header = map (:[]) (take ((length $ head xs) - 1) ['A'..]) ++ [name] |
||
pad s = s ++ replicate (5 - length s) ' '</ |
pad s = s ++ replicate (5 - length s) ' '</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,634: | Line 2,634: | ||
< |
<syntaxhighlight lang="icon">$define TRUE 1 |
||
$define FALSE -1 |
$define FALSE -1 |
||
$define UNKNOWN 0 |
$define UNKNOWN 0 |
||
Line 2,695: | Line 2,695: | ||
procedure xor3(a,b) #: xor of two trits or error if invalid |
procedure xor3(a,b) #: xor of two trits or error if invalid |
||
return not3(eq3(a,b)) |
return not3(eq3(a,b)) |
||
end</ |
end</syntaxhighlight> |
||
{{libheader|Icon Programming Library}} |
{{libheader|Icon Programming Library}} |
||
Line 2,746: | Line 2,746: | ||
maybe: 0.5 |
maybe: 0.5 |
||
< |
<syntaxhighlight lang="j">not=: -. |
||
and=: <. |
and=: <. |
||
or =: >. |
or =: >. |
||
if =: (>. -.)"0~ |
if =: (>. -.)"0~ |
||
eq =: (<.&-. >. <.)"0</ |
eq =: (<.&-. >. <.)"0</syntaxhighlight> |
||
Example use: |
Example use: |
||
< |
<syntaxhighlight lang="j"> not 0 0.5 1 |
||
1 0.5 0 |
1 0.5 0 |
||
Line 2,775: | Line 2,775: | ||
1 0.5 0 |
1 0.5 0 |
||
0.5 0.5 0.5 |
0.5 0.5 0.5 |
||
0 0.5 1</ |
0 0.5 1</syntaxhighlight> |
||
Note that this implementation is a special case of "[[wp:fuzzy logic|fuzzy logic]]" (using a limited set of values). |
Note that this implementation is a special case of "[[wp:fuzzy logic|fuzzy logic]]" (using a limited set of values). |
||
Line 2,783: | Line 2,783: | ||
Note that we might instead define values between 0 and 1 to represent independent probabilities: |
Note that we might instead define values between 0 and 1 to represent independent probabilities: |
||
< |
<syntaxhighlight lang="j">not=: -. |
||
and=: * |
and=: * |
||
or=: *&.-. |
or=: *&.-. |
||
if =: (or -.)"0~ |
if =: (or -.)"0~ |
||
eq =: (*&-. or *)"0</ |
eq =: (*&-. or *)"0</syntaxhighlight> |
||
However, while this might be a more intellectually satisfying approach, this gives us some different results from the task requirement, for the combination of two "maybe" values (we could "fix" this by adding some "logic" which replaced any non-integer value with "0.5" - this would satisfy literal compliance with the task specification and might even be a valid engineering choice if we are implementing in hardware, for example): |
However, while this might be a more intellectually satisfying approach, this gives us some different results from the task requirement, for the combination of two "maybe" values (we could "fix" this by adding some "logic" which replaced any non-integer value with "0.5" - this would satisfy literal compliance with the task specification and might even be a valid engineering choice if we are implementing in hardware, for example): |
||
< |
<syntaxhighlight lang="j"> not 0 0.5 1 |
||
1 0.5 0 |
1 0.5 0 |
||
Line 2,812: | Line 2,812: | ||
1 0.5 0 |
1 0.5 0 |
||
0.5 0.4375 0.5 |
0.5 0.4375 0.5 |
||
0 0.5 1</ |
0 0.5 1</syntaxhighlight> |
||
Another interesting possibility would involve using George Boole's original operations. This leaves us without any "not", (if we include the definition of logical negation which was later added to the definition of Boolean algebra, then the only numbers which can be used with Boolean algebra are 1 and 0). So, it's not clear how we would implement "if" or "eq". However, "and" and "or" would look like this: |
Another interesting possibility would involve using George Boole's original operations. This leaves us without any "not", (if we include the definition of logical negation which was later added to the definition of Boolean algebra, then the only numbers which can be used with Boolean algebra are 1 and 0). So, it's not clear how we would implement "if" or "eq". However, "and" and "or" would look like this: |
||
< |
<syntaxhighlight lang="j">and=: *. |
||
or=: +.</ |
or=: +.</syntaxhighlight> |
||
And, the boolean result tables would look like this: |
And, the boolean result tables would look like this: |
||
< |
<syntaxhighlight lang="j"> 0 0.5 1 and/ 0 0.5 1 |
||
0 0 0 |
0 0 0 |
||
0 0.5 1 |
0 0.5 1 |
||
Line 2,829: | Line 2,829: | ||
0 0.5 1 |
0 0.5 1 |
||
0.5 0.5 0.5 |
0.5 0.5 0.5 |
||
1 0.5 1</ |
1 0.5 1</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
{{works with|Java|1.5+}} |
{{works with|Java|1.5+}} |
||
< |
<syntaxhighlight lang="java5">public class Logic{ |
||
public static enum Trit{ |
public static enum Trit{ |
||
TRUE, MAYBE, FALSE; |
TRUE, MAYBE, FALSE; |
||
Line 2,900: | Line 2,900: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>not TRUE: FALSE |
<pre>not TRUE: FALSE |
||
Line 2,918: | Line 2,918: | ||
Let's use the trit already available in JavaScript: |
Let's use the trit already available in JavaScript: |
||
true, false (both boolean) and undefined… |
true, false (both boolean) and undefined… |
||
< |
<syntaxhighlight lang="javascript">var L3 = new Object(); |
||
L3.not = function(a) { |
L3.not = function(a) { |
||
Line 2,951: | Line 2,951: | ||
return L3.and(L3.ifThen(a, b), L3.ifThen(b, a)); |
return L3.and(L3.ifThen(a, b), L3.ifThen(b, a)); |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
… and try these: |
… and try these: |
||
<lang> |
<syntaxhighlight lang="text"> |
||
L3.not(true) // false |
L3.not(true) // false |
||
L3.not(var a) // undefined |
L3.not(var a) // undefined |
||
Line 2,964: | Line 2,964: | ||
L3.iff(a, 2 == 2) // undefined |
L3.iff(a, 2 == 2) // undefined |
||
</syntaxhighlight> |
|||
</lang> |
|||
Here is a compact solution |
Here is a compact solution |
||
<syntaxhighlight lang="javascript"> |
|||
<lang Javascript> |
|||
trit = {false: 'F', maybe: 'U', true: 'T'} |
trit = {false: 'F', maybe: 'U', true: 'T'} |
||
nand = (a, b) => (a == trit.false || b == trit.false) ? trit.true : (a == trit.maybe || b == trit.maybe) ? trit.maybe : trit.false |
nand = (a, b) => (a == trit.false || b == trit.false) ? trit.true : (a == trit.maybe || b == trit.maybe) ? trit.maybe : trit.false |
||
Line 2,976: | Line 2,976: | ||
iff = (a, b) => or(and(a, b), nor(a, b)) |
iff = (a, b) => or(and(a, b), nor(a, b)) |
||
xor = (a, b) => not(iff(a, b)) |
xor = (a, b) => not(iff(a, b)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
... to test it |
... to test it |
||
<syntaxhighlight lang="javascript"> |
|||
<lang Javascript> |
|||
functor = {nand, and, or, nor, implies, iff, xor} |
functor = {nand, and, or, nor, implies, iff, xor} |
||
display = {nand: '⊼', and: '∧', or: '∨', nor: '⊽', implies: '⇒', iff: '⇔', xor: '⊻', not: '¬'} |
display = {nand: '⊼', and: '∧', or: '∨', nor: '⊽', implies: '⇒', iff: '⇔', xor: '⊻', not: '¬'} |
||
Line 2,994: | Line 2,994: | ||
} |
} |
||
console.log(log) |
console.log(log) |
||
</syntaxhighlight> |
|||
</lang> |
|||
...Output: |
...Output: |
||
<lang> |
<syntaxhighlight lang="text"> |
||
NOT |
NOT |
||
¬F = F |
¬F = F |
||
Line 3,012: | Line 3,012: | ||
T ⊼ U = U T ∧ U = U T ∨ U = T T ⊽ U = F T ⇒ U = U T ⇔ U = U T ⊻ U = U |
T ⊼ U = U T ∧ U = U T ∨ U = T T ⊽ U = F T ⇒ U = U T ⇔ U = U T ⊻ U = U |
||
T ⊼ T = F T ∧ T = T T ∨ T = T T ⊽ T = F T ⇒ T = T T ⇔ T = T T ⊻ T = F |
T ⊼ T = F T ∧ T = T T ∨ T = T T ⊽ T = F T ⇒ T = T T ⇔ T = T T ⊻ T = F |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|jq}}== |
=={{header|jq}}== |
||
Line 3,018: | Line 3,018: | ||
as the three values since ternary logic agrees with Boolean logic for true and false, and because jq prints these three values consistently. |
as the three values since ternary logic agrees with Boolean logic for true and false, and because jq prints these three values consistently. |
||
For consistency, all the ternary logic operators are defined here with the prefix "ternary_", but such a prefix is only needed for "not", "and", and "or", as these are jq keywords. < |
For consistency, all the ternary logic operators are defined here with the prefix "ternary_", but such a prefix is only needed for "not", "and", and "or", as these are jq keywords. <syntaxhighlight lang="jq">def ternary_nand(a; b): |
||
if a == false or b == false then true |
if a == false or b == false then true |
||
elif a == "maybe" or b == "maybe" then "maybe" |
elif a == "maybe" or b == "maybe" then "maybe" |
||
Line 3,050: | Line 3,050: | ||
display_equiv( (false, "maybe", true ); (false, "maybe", true) ), |
display_equiv( (false, "maybe", true ); (false, "maybe", true) ), |
||
"etc etc" |
"etc etc" |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>"false and false is false" |
<pre>"false and false is false" |
||
Line 3,076: | Line 3,076: | ||
{{works with|Julia|0.6}} |
{{works with|Julia|0.6}} |
||
< |
<syntaxhighlight lang="julia">@enum Trit False Maybe True |
||
const trits = (False, Maybe, True) |
const trits = (False, Maybe, True) |
||
Line 3,102: | Line 3,102: | ||
for a in trits |
for a in trits |
||
println(join(@sprintf("%10s ≡ %5s is %5s", a, b, a ≡ b) for b in trits)) |
println(join(@sprintf("%10s ≡ %5s is %5s", a, b, a ≡ b) for b in trits)) |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,129: | Line 3,129: | ||
With Julia 1.0 and the new type <tt>missing</tt>, three-value logic is implemented by default |
With Julia 1.0 and the new type <tt>missing</tt>, three-value logic is implemented by default |
||
< |
<syntaxhighlight lang="julia"># built-in: true, false and missing |
||
using Printf |
using Printf |
||
Line 3,160: | Line 3,160: | ||
for (A, B) in Iterators.product(tril, tril) |
for (A, B) in Iterators.product(tril, tril) |
||
@printf("%8s | %8s | %8s\n", A, B, A ⊃ B) |
@printf("%8s | %8s | %8s\n", A, B, A ⊃ B) |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,212: | Line 3,212: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
< |
<syntaxhighlight lang="scala">// version 1.1.2 |
||
enum class Trit { |
enum class Trit { |
||
Line 3,297: | Line 3,297: | ||
println() |
println() |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,336: | Line 3,336: | ||
{{works with|langur|0.6.12}} |
{{works with|langur|0.6.12}} |
||
< |
<syntaxhighlight lang="langur"># borrowing null for "maybe" |
||
val .trSet = [false, null, true] |
val .trSet = [false, null, true] |
||
Line 3,391: | Line 3,391: | ||
writeln $"\.a:.F; \.b:.F; \.a ==? .b:.F;" |
writeln $"\.a:.F; \.b:.F; \.a ==? .b:.F;" |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,444: | Line 3,444: | ||
=={{header|Liberty BASIC}}== |
=={{header|Liberty BASIC}}== |
||
<syntaxhighlight lang="lb"> |
|||
<lang lb> |
|||
'ternary logic |
'ternary logic |
||
'0 1 2 |
'0 1 2 |
||
Line 3,515: | Line 3,515: | ||
longName3$ = word$("False,Don't know,True", i+1, ",") |
longName3$ = word$("False,Don't know,True", i+1, ",") |
||
end function |
end function |
||
</ |
</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,548: | Line 3,548: | ||
The following script generates all truth tables for Maple logical operations. Note that in addition to the usual built-in logical operators for '''not''', '''or''', '''and''', and '''xor''', Maple also has '''implies'''. |
The following script generates all truth tables for Maple logical operations. Note that in addition to the usual built-in logical operators for '''not''', '''or''', '''and''', and '''xor''', Maple also has '''implies'''. |
||
< |
<syntaxhighlight lang="maple">tv := [true, false, FAIL]; |
||
NotTable := Array(1..3, i->not tv[i] ); |
NotTable := Array(1..3, i->not tv[i] ); |
||
AndTable := Array(1..3, 1..3, (i,j)->tv[i] and tv[j] ); |
AndTable := Array(1..3, 1..3, (i,j)->tv[i] and tv[j] ); |
||
OrTable := Array(1..3, 1..3, (i,j)->tv[i] or tv[j] ); |
OrTable := Array(1..3, 1..3, (i,j)->tv[i] or tv[j] ); |
||
XorTable := Array(1..3, 1..3, (i,j)->tv[i] xor tv[j] ); |
XorTable := Array(1..3, 1..3, (i,j)->tv[i] xor tv[j] ); |
||
ImpliesTable := Array(1..3, 1..3, (i,j)->tv[i] implies tv[j] );</ |
ImpliesTable := Array(1..3, 1..3, (i,j)->tv[i] implies tv[j] );</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
< |
<syntaxhighlight lang="maple">> tv := [true, false, FAIL]; |
||
tv := [true, false, FAIL] |
tv := [true, false, FAIL] |
||
Line 3,589: | Line 3,589: | ||
ImpliesTable := [true true true] |
ImpliesTable := [true true true] |
||
[ ] |
[ ] |
||
[true FAIL FAIL]</ |
[true FAIL FAIL]</syntaxhighlight> |
||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
Type definition is not allowed in Mathematica. We can just use the build-in symbols "True" and "False", and add a new symbol "Maybe". |
Type definition is not allowed in Mathematica. We can just use the build-in symbols "True" and "False", and add a new symbol "Maybe". |
||
< |
<syntaxhighlight lang="mathematica">Maybe /: ! Maybe = Maybe; |
||
Maybe /: (And | Or | Nand | Nor | Xor | Xnor | Implies | Equivalent)[Maybe, Maybe] = Maybe;</ |
Maybe /: (And | Or | Nand | Nor | Xor | Xnor | Implies | Equivalent)[Maybe, Maybe] = Maybe;</syntaxhighlight> |
||
Example: |
Example: |
||
< |
<syntaxhighlight lang="mathematica">trits = {True, Maybe, False}; |
||
Print@Grid[ |
Print@Grid[ |
||
ArrayFlatten[{{{{Not}}, {{Null}}}, {List /@ trits, |
ArrayFlatten[{{{{Not}}, {{Null}}}, {List /@ trits, |
||
Line 3,604: | Line 3,604: | ||
Null}}}, {{{Null}}, {trits}}, {List /@ trits, |
Null}}}, {{{Null}}, {trits}}, {List /@ trits, |
||
Outer[operator, trits, trits]}}]], {operator, {And, Or, Nand, |
Outer[operator, trits, trits]}}]], {operator, {And, Or, Nand, |
||
Nor, Xor, Xnor, Implies, Equivalent}}]</ |
Nor, Xor, Xnor, Implies, Equivalent}}]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Not |
<pre>Not |
||
Line 3,668: | Line 3,668: | ||
=={{header|МК-61/52}}== |
=={{header|МК-61/52}}== |
||
<lang>П0 Сx С/П ^ 1 + 3 * + 1 |
<syntaxhighlight lang="text">П0 Сx С/П ^ 1 + 3 * + 1 |
||
+ 3 x^y ИП0 <-> / [x] ^ ^ 3 |
+ 3 x^y ИП0 <-> / [x] ^ ^ 3 |
||
/ [x] 3 * - 1 - С/П 1 5 |
/ [x] 3 * - 1 - С/П 1 5 |
||
6 3 3 БП 00 1 9 5 6 9 |
6 3 3 БП 00 1 9 5 6 9 |
||
БП 00 1 5 9 2 9 БП 00 1 |
БП 00 1 5 9 2 9 БП 00 1 |
||
5 6 6 5 БП 00 /-/ ЗН С/П</ |
5 6 6 5 БП 00 /-/ ЗН С/П</syntaxhighlight> |
||
<u>Instruction</u>: |
<u>Instruction</u>: |
||
Line 3,684: | Line 3,684: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
< |
<syntaxhighlight lang="nim">type Trit* = enum ttrue, tmaybe, tfalse |
||
proc `$`*(a: Trit): string = |
proc `$`*(a: Trit): string = |
||
Line 3,739: | Line 3,739: | ||
echo "$# or $#: $#".format(op1, op2, op1 or op2) |
echo "$# or $#: $#".format(op1, op2, op1 or op2) |
||
echo "$# then $#: $#".format(op1, op2, op1.then op2) |
echo "$# then $#: $#".format(op1, op2, op1.then op2) |
||
echo "$# equiv $#: $#".format(op1, op2, op1.equiv op2)</ |
echo "$# equiv $#: $#".format(op1, op2, op1.equiv op2)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Not T: F |
<pre>Not T: F |
||
Line 3,783: | Line 3,783: | ||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
< |
<syntaxhighlight lang="ocaml">type trit = True | False | Maybe |
||
let t_not = function |
let t_not = function |
||
Line 3,826: | Line 3,826: | ||
print t_imply "Then"; |
print t_imply "Then"; |
||
print t_eq "Equiv"; |
print t_eq "Equiv"; |
||
;;</ |
;;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,876: | Line 3,876: | ||
=== Using a general binary -> ternary transform === |
=== Using a general binary -> ternary transform === |
||
Instead of writing all of the truth-tables by hand, we can construct a general binary -> ternary transform and apply it to any logical function we want: |
Instead of writing all of the truth-tables by hand, we can construct a general binary -> ternary transform and apply it to any logical function we want: |
||
< |
<syntaxhighlight lang="ocaml">type trit = True | False | Maybe |
||
let to_bin = function True -> [true] | False -> [false] | Maybe -> [true;false] |
let to_bin = function True -> [true] | False -> [false] | Maybe -> [true;false] |
||
Line 3,915: | Line 3,915: | ||
table2 "or" t_or;; |
table2 "or" t_or;; |
||
table2 "equiv" t_equiv;; |
table2 "equiv" t_equiv;; |
||
table2 "implies" t_imply;;</ |
table2 "implies" t_imply;;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,968: | Line 3,968: | ||
=={{header|ooRexx}}== |
=={{header|ooRexx}}== |
||
<syntaxhighlight lang="oorexx"> |
|||
<lang ooRexx> |
|||
tritValues = .array~of(.trit~true, .trit~false, .trit~maybe) |
tritValues = .array~of(.trit~true, .trit~false, .trit~maybe) |
||
tab = '09'x |
tab = '09'x |
||
Line 4,093: | Line 4,093: | ||
else if self == .trit~maybe then return .trit~maybe |
else if self == .trit~maybe then return .trit~maybe |
||
else return \other |
else return \other |
||
</syntaxhighlight> |
|||
</lang> |
|||
<pre> |
<pre> |
||
Line 4,147: | Line 4,147: | ||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
< |
<syntaxhighlight lang="pascal">Program TernaryLogic (output); |
||
type |
type |
||
Line 4,237: | Line 4,237: | ||
writeln('False ', terToStr(terEquals(terTrue,terFalse)), ' ', terToStr(terEquals(terMayBe,terFalse)), ' ', terToStr(terEquals(terFalse,terFalse))); |
writeln('False ', terToStr(terEquals(terTrue,terFalse)), ' ', terToStr(terEquals(terMayBe,terFalse)), ' ', terToStr(terEquals(terFalse,terFalse))); |
||
writeln; |
writeln; |
||
end.</ |
end.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 4,270: | Line 4,270: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
File <TT>Trit.pm</TT>: |
File <TT>Trit.pm</TT>: |
||
< |
<syntaxhighlight lang="perl">package Trit; |
||
# -1 = false ; 0 = maybe ; 1 = true |
# -1 = false ; 0 = maybe ; 1 = true |
||
Line 4,339: | Line 4,339: | ||
sub or { new Trit(max(${$_[0]}, ${$_[1]}) ) } |
sub or { new Trit(max(${$_[0]}, ${$_[1]}) ) } |
||
sub equiv { new Trit( ${$_[0]} * ${$_[1]} ) }</ |
sub equiv { new Trit( ${$_[0]} * ${$_[1]} ) }</syntaxhighlight> |
||
File <TT>test.pl</TT>: |
File <TT>test.pl</TT>: |
||
< |
<syntaxhighlight lang="perl">use Trit ':all'; |
||
my @a = (TRUE(), MAYBE(), FALSE()); |
my @a = (TRUE(), MAYBE(), FALSE()); |
||
Line 4,383: | Line 4,383: | ||
} |
} |
||
print "\n"; |
print "\n"; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>a NOT a |
<pre>a NOT a |
||
Line 4,412: | Line 4,412: | ||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
{{libheader|Phix/basics}} |
{{libheader|Phix/basics}} |
||
<!--< |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #008080;">enum</span> <span style="color: #000000;">T</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">M</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">F</span> |
<span style="color: #008080;">enum</span> <span style="color: #000000;">T</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">M</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">F</span> |
||
<span style="color: #008080;">type</span> <span style="color: #000000;">ternary</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">T</span><span style="color: #0000FF;">,</span><span style="color: #000000;">M</span><span style="color: #0000FF;">,</span><span style="color: #000000;">F</span><span style="color: #0000FF;">})</span> <span style="color: #008080;">end</span> <span style="color: #008080;">type</span> |
<span style="color: #008080;">type</span> <span style="color: #000000;">ternary</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">T</span><span style="color: #0000FF;">,</span><span style="color: #000000;">M</span><span style="color: #0000FF;">,</span><span style="color: #000000;">F</span><span style="color: #0000FF;">})</span> <span style="color: #008080;">end</span> <span style="color: #008080;">type</span> |
||
Line 4,467: | Line 4,467: | ||
<span style="color: #000000;">show_truth_table</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t_implies</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"imp"</span><span style="color: #0000FF;">)</span> |
<span style="color: #000000;">show_truth_table</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t_implies</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"imp"</span><span style="color: #0000FF;">)</span> |
||
<span style="color: #000000;">show_truth_table</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t_equal</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"eq"</span><span style="color: #0000FF;">)</span> |
<span style="color: #000000;">show_truth_table</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t_equal</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"eq"</span><span style="color: #0000FF;">)</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 4,509: | Line 4,509: | ||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
Save the sample code as executable shell script on your *nix system: |
Save the sample code as executable shell script on your *nix system: |
||
< |
<syntaxhighlight lang="php">#!/usr/bin/php |
||
<?php |
<?php |
||
Line 4,571: | Line 4,571: | ||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Sample output: |
Sample output: |
||
<pre>--- Sample output for a equivalent b --- |
<pre>--- Sample output for a equivalent b --- |
||
Line 4,587: | Line 4,587: | ||
=={{header|Picat}}== |
=={{header|Picat}}== |
||
< |
<syntaxhighlight lang="picat">main => |
||
(show_op1('!') ; true), |
(show_op1('!') ; true), |
||
nl, |
nl, |
||
Line 4,644: | Line 4,644: | ||
nl |
nl |
||
end, |
end, |
||
nl.</ |
nl.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 4,679: | Line 4,679: | ||
===Simple examples=== |
===Simple examples=== |
||
< |
<syntaxhighlight lang="picat">main => |
||
println(ternary(10 > 3,'->',maybe).ternary('!')), |
println(ternary(10 > 3,'->',maybe).ternary('!')), |
||
println(ternary(4 < 18,'/\\',$not membchk('a',"picat")).ternary('->',maybe).ternary('==',true)).</ |
println(ternary(4 < 18,'/\\',$not membchk('a',"picat")).ternary('->',maybe).ternary('==',true)).</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 4,689: | Line 4,689: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
In addition for the standard T (for "true") and NIL (for "false") we define 0 (zero, for "maybe"). |
In addition for the standard T (for "true") and NIL (for "false") we define 0 (zero, for "maybe"). |
||
< |
<syntaxhighlight lang="picolisp">(de 3not (A) |
||
(or (=0 A) (not A)) ) |
(or (=0 A) (not A)) ) |
||
Line 4,713: | Line 4,713: | ||
((=T A) B) |
((=T A) B) |
||
((=0 A) 0) |
((=0 A) 0) |
||
(T (3not B)) ) )</ |
(T (3not B)) ) )</syntaxhighlight> |
||
Test: |
Test: |
||
< |
<syntaxhighlight lang="picolisp">(for X '(T 0 NIL) |
||
(println 'not X '-> (3not X)) ) |
(println 'not X '-> (3not X)) ) |
||
Line 4,721: | Line 4,721: | ||
(for X '(T 0 NIL) |
(for X '(T 0 NIL) |
||
(for Y '(T 0 NIL) |
(for Y '(T 0 NIL) |
||
(println X (car Fun) Y '-> ((cdr Fun) X Y)) ) ) )</ |
(println X (car Fun) Y '-> ((cdr Fun) X Y)) ) ) )</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>not T -> NIL |
<pre>not T -> NIL |
||
Line 4,765: | Line 4,765: | ||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
{{trans|FreeBasic}} |
{{trans|FreeBasic}} |
||
< |
<syntaxhighlight lang="purebasic">DataSection |
||
TLogic: |
TLogic: |
||
Data.i -1,0,1 |
Data.i -1,0,1 |
||
Line 4,822: | Line 4,822: | ||
Next |
Next |
||
EndIf |
EndIf |
||
Input()</ |
Input()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> (AND) ( OR) (EQV) (IMP) (NOT) |
<pre> (AND) ( OR) (EQV) (IMP) (NOT) |
||
Line 4,834: | Line 4,834: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
In Python, the keywords 'and', 'not', and 'or' are coerced to always work as boolean operators. I have therefore overloaded the boolean bitwise operators &, |, ^ to provide the required functionality. |
In Python, the keywords 'and', 'not', and 'or' are coerced to always work as boolean operators. I have therefore overloaded the boolean bitwise operators &, |, ^ to provide the required functionality. |
||
< |
<syntaxhighlight lang="python">class Trit(int): |
||
def __new__(cls, value): |
def __new__(cls, value): |
||
if value == 'TRUE': |
if value == 'TRUE': |
||
Line 4,962: | Line 4,962: | ||
for b in values: |
for b in values: |
||
expr = '%s %s %s' % (a, op, b) |
expr = '%s %s %s' % (a, op, b) |
||
print(' %s = %s' % (expr, eval(expr)))</ |
print(' %s = %s' % (expr, eval(expr)))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 5,014: | Line 5,014: | ||
=={{header|Quackery}}== |
=={{header|Quackery}}== |
||
<syntaxhighlight lang="quackery "> |
|||
<lang Quackery > |
|||
[ 2 ] is maybe ( --> t ) |
[ 2 ] is maybe ( --> t ) |
||
Line 5,119: | Line 5,119: | ||
say " false | " false true t.<=> paddedtrit sp |
say " false | " false true t.<=> paddedtrit sp |
||
say "| " false maybe t.<=> paddedtrit sp |
say "| " false maybe t.<=> paddedtrit sp |
||
say "| " false false t.<=> paddedtrit cr</ |
say "| " false false t.<=> paddedtrit cr</syntaxhighlight> |
||
'''Output:''' |
'''Output:''' |
||
Line 5,152: | Line 5,152: | ||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang="racket">#lang typed/racket |
||
; to avoid the hassle of adding a maybe value that is as special as |
; to avoid the hassle of adding a maybe value that is as special as |
||
Line 5,213: | Line 5,213: | ||
(for*: : Void ([a (in-list '(true maybe false))] |
(for*: : Void ([a (in-list '(true maybe false))] |
||
[b (in-list '(true maybe false))]) |
[b (in-list '(true maybe false))]) |
||
(printf "~a ~a ~a = ~a~n" a (object-name proc) b (proc a b))))</ |
(printf "~a ~a ~a = ~a~n" a (object-name proc) b (proc a b))))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 5,263: | Line 5,263: | ||
The precedence of each operator is specified as equivalent to an existing operator. We've taken the liberty of using a double arrow for implication, to avoid confusing it with <tt>⊃</tt>, (U+2283 SUPERSET OF). |
The precedence of each operator is specified as equivalent to an existing operator. We've taken the liberty of using a double arrow for implication, to avoid confusing it with <tt>⊃</tt>, (U+2283 SUPERSET OF). |
||
<lang |
<syntaxhighlight lang="raku" line># Implementation: |
||
enum Trit <Foo Moo Too>; |
enum Trit <Foo Moo Too>; |
||
Line 5,309: | Line 5,309: | ||
Foo ∧ Too ∨ Foo ⇒ Foo ≡ Too, |
Foo ∧ Too ∨ Foo ⇒ Foo ≡ Too, |
||
Foo ∧ Too ∨ Too ⇒ Foo ≡ Foo, |
Foo ∧ Too ∨ Too ⇒ Foo ≡ Foo, |
||
);</ |
);</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 5,347: | Line 5,347: | ||
{{Works with|Red|0.6.4}} |
{{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 |
; define trits as a set of 3 Red words: 'oui, 'non and 'bof |
||
Line 5,399: | Line 5,399: | ||
print rejoin [pad mold s 25 " " do s] |
print rejoin [pad mold s 25 " " do s] |
||
] |
] |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 5,416: | Line 5,416: | ||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
This REXX program is a re-worked version of the REXX program used for the Rosetta Code task: ''truth table''. |
This REXX program is a re-worked version of the REXX program used for the Rosetta Code task: ''truth table''. |
||
< |
<syntaxhighlight lang="rexx">/*REXX program displays a ternary truth table [true, false, maybe] for the variables */ |
||
/*──── and one or more expressions. */ |
/*──── and one or more expressions. */ |
||
/*──── Infix notation is supported with one character propositional constants. */ |
/*──── Infix notation is supported with one character propositional constants. */ |
||
Line 5,611: | Line 5,611: | ||
otherwise return -13 /*error, unknown function.*/ |
otherwise return -13 /*error, unknown function.*/ |
||
end /*select*/ |
end /*select*/ |
||
</syntaxhighlight> |
|||
</lang> |
|||
Some older REXXes don't have a '''changestr''' BIF, so one is included here ──► [[CHANGESTR.REX]]. |
Some older REXXes don't have a '''changestr''' BIF, so one is included here ──► [[CHANGESTR.REX]]. |
||
<br><br> |
<br><br> |
||
Line 5,695: | Line 5,695: | ||
{{works with|Ruby|1.9}} |
{{works with|Ruby|1.9}} |
||
< |
<syntaxhighlight lang="ruby"># trit.rb - ternary logic |
||
# http://rosettacode.org/wiki/Ternary_logic |
# http://rosettacode.org/wiki/Ternary_logic |
||
Line 5,779: | Line 5,779: | ||
# false.trit == obj # => false, maybe or true |
# false.trit == obj # => false, maybe or true |
||
def trit; TritMagic; end |
def trit; TritMagic; end |
||
end</ |
end</syntaxhighlight> |
||
This IRB session shows ternary not, and, or, equal. |
This IRB session shows ternary not, and, or, equal. |
||
< |
<syntaxhighlight lang="ruby">$ irb |
||
irb(main):001:0> require './trit' |
irb(main):001:0> require './trit' |
||
=> true |
=> true |
||
Line 5,799: | Line 5,799: | ||
=> false |
=> false |
||
irb(main):008:0> false.trit == maybe |
irb(main):008:0> false.trit == maybe |
||
=> maybe</ |
=> maybe</syntaxhighlight> |
||
This program shows all 9 outcomes from <code>a.trit ^ b</code>. |
This program shows all 9 outcomes from <code>a.trit ^ b</code>. |
||
< |
<syntaxhighlight lang="ruby">require 'trit' |
||
maybe = MAYBE |
maybe = MAYBE |
||
Line 5,810: | Line 5,810: | ||
printf "%5s ^ %5s => %5s\n", a, b, a.trit ^ b |
printf "%5s ^ %5s => %5s\n", a, b, a.trit ^ b |
||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
<pre>$ ruby -I. trit-xor.rb |
<pre>$ ruby -I. trit-xor.rb |
||
Line 5,824: | Line 5,824: | ||
=={{header|Run BASIC}}== |
=={{header|Run BASIC}}== |
||
< |
<syntaxhighlight lang="runbasic">testFalse = 0 ' F |
||
testDoNotKnow = 1 ' ? |
testDoNotKnow = 1 ' ? |
||
testTrue = 2 ' T |
testTrue = 2 ' T |
||
Line 5,881: | Line 5,881: | ||
function longName3$(i) |
function longName3$(i) |
||
longName3$ = word$("False,Don't know,True", i+1, ",") |
longName3$ = word$("False,Don't know,True", i+1, ",") |
||
end function</ |
end function</syntaxhighlight><pre>Short and long names for ternary logic values |
||
F False |
F False |
||
? Don't know |
? Don't know |
||
Line 5,897: | Line 5,897: | ||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
{{trans|Kotlin}} |
{{trans|Kotlin}} |
||
< |
<syntaxhighlight lang="rust">use std::{ops, fmt}; |
||
#[derive(Copy, Clone, Debug)] |
#[derive(Copy, Clone, Debug)] |
||
Line 6,003: | Line 6,003: | ||
println!(); |
println!(); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 6,037: | Line 6,037: | ||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
< |
<syntaxhighlight lang="scala">sealed trait Trit { self => |
||
def nand(that:Trit):Trit=(this,that) match { |
def nand(that:Trit):Trit=(this,that) match { |
||
case (TFalse, _) => TTrue |
case (TFalse, _) => TTrue |
||
Line 6,069: | Line 6,069: | ||
println("\n- Equiv -") |
println("\n- Equiv -") |
||
for(a<-v; b<-v) println("%6s : %6s => %6s".format(a, b, a equiv b)) |
for(a<-v; b<-v) println("%6s : %6s => %6s".format(a, b, a equiv b)) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>- NOT - |
<pre>- NOT - |
||
Line 6,139: | Line 6,139: | ||
which use also short circuit evaluation. |
which use also short circuit evaluation. |
||
< |
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i"; |
||
const type: trit is new enum |
const type: trit is new enum |
||
Line 6,252: | Line 6,252: | ||
writeTable(operand1 -> operand2, "->"); |
writeTable(operand1 -> operand2, "->"); |
||
writeTable(operand1 == operand2, "=="); |
writeTable(operand1 == operand2, "=="); |
||
end func;</ |
end func;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 6,293: | Line 6,293: | ||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
The simplest way of doing this is by constructing the operations as truth tables. The code below uses an abbreviated form of truth table. |
The simplest way of doing this is by constructing the operations as truth tables. The code below uses an abbreviated form of truth table. |
||
< |
<syntaxhighlight lang="tcl">package require Tcl 8.5 |
||
namespace eval ternary { |
namespace eval ternary { |
||
# Code generator |
# Code generator |
||
Line 6,359: | Line 6,359: | ||
* false |
* false |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Demonstrating: |
Demonstrating: |
||
< |
<syntaxhighlight lang="tcl">namespace import ternary::* |
||
puts "x /\\ y == x \\/ y" |
puts "x /\\ y == x \\/ y" |
||
puts " x | y || result" |
puts " x | y || result" |
||
Line 6,370: | Line 6,370: | ||
puts [format " %-5s | %-5s || %-5s" $x $y $z] |
puts [format " %-5s | %-5s || %-5s" $x $y $z] |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 6,390: | Line 6,390: | ||
=={{header|True BASIC}}== |
=={{header|True BASIC}}== |
||
{{trans|BASIC256}} |
{{trans|BASIC256}} |
||
< |
<syntaxhighlight lang="basic"> |
||
FUNCTION and3(a, b) |
FUNCTION and3(a, b) |
||
IF a < b then LET and3 = a else LET and3 = b |
IF a < b then LET and3 = a else LET and3 = b |
||
Line 6,457: | Line 6,457: | ||
NEXT a |
NEXT a |
||
END |
END |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 6,475: | Line 6,475: | ||
Below is an example of how this would look, which can be compared to traditional ternary usage: |
Below is an example of how this would look, which can be compared to traditional ternary usage: |
||
< |
<syntaxhighlight lang="vlang">import math |
||
fn main() { |
fn main() { |
||
Line 6,537: | Line 6,537: | ||
fn ternary_equiv(a f64, b f64) string { |
fn ternary_equiv(a f64, b f64) string { |
||
return if a == b {'1.'} else if a == 1 {b.str()} else if b == 1 {a.str()} else {'0.5'} |
return if a == b {'1.'} else if a == 1 {b.str()} else if b == 1 {a.str()} else {'0.5'} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 6,587: | Line 6,587: | ||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
< |
<syntaxhighlight lang="ecmascript">var False = -1 |
||
var Maybe = 0 |
var Maybe = 0 |
||
var True = 1 |
var True = 1 |
||
Line 6,649: | Line 6,649: | ||
for (u in trits) System.write("%(t == u) ") |
for (u in trits) System.write("%(t == u) ") |
||
System.print() |
System.print() |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 6,686: | Line 6,686: | ||
=={{header|Yabasic}}== |
=={{header|Yabasic}}== |
||
{{trans|BASIC256}} |
{{trans|BASIC256}} |
||
< |
<syntaxhighlight lang="yabasic"> |
||
tFalse = 0 |
tFalse = 0 |
||
tDontKnow = 1 |
tDontKnow = 1 |
||
Line 6,755: | Line 6,755: | ||
next a |
next a |
||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |