Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,3 @@
---
from: http://rosettacode.org/wiki/Ternary_logic
note: Logic

View file

@ -0,0 +1,92 @@
<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'':'''
|-
|
{| class=wikitable
|+''not'' a
|-
! colspan=2 | &not;
|-
| True || False
|-
| Maybe || Maybe
|-
| False || True
|}
||
{| class=wikitable
|+a ''and'' b
|-
! &and;
| True || Maybe || False
|-
| True || True || Maybe || False
|-
| Maybe || Maybe || Maybe || False
|-
| False || False || False || False
|}
||
{| class=wikitable
|-
|+a ''or'' b
|-
! &or;
| True || Maybe || False
|-
| True || True || True || True
|-
| Maybe || True || Maybe || Maybe
|-
| False || True || Maybe || False
|}
|-
||
{| class=wikitable
|-
|+''if'' a ''then'' b
|-
! ⊃
| True || Maybe || False
|-
| True || True || Maybe || False
|-
| Maybe || True || Maybe || Maybe
|-
| False || True || True || True
|}
||
{| class=wikitable
|-
|+a ''is equivalent to'' b
|-
! ≡
| True || Maybe || False
|-
| True || True || Maybe || False
|-
| Maybe || Maybe || Maybe || Maybe
|-
| False || False || Maybe || True
|}
|}
;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.
<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>

View file

@ -0,0 +1,99 @@
# -*- coding: utf-8 -*- #
INT trit width = 1, trit base = 3;
MODE TRIT = STRUCT(BITS trit);
CO FORMAT trit fmt = $c("?","⌈","⌊",#|"~"#)$; CO
# These values treated are as per "Balanced ternary" #
# eg true=1, maybe=0, false=-1 #
TRIT true =INITTRIT 4r1, maybe=INITTRIT 4r0,
false=INITTRIT 4r2;
# Warning: redefines standard builtins flip & flop #
LONGCHAR flap="?", flip="⌈", flop="⌊";
OP REPR = (TRIT t)LONGCHAR:
[]LONGCHAR(flap, flip, flop)[1+ABS trit OF t];
############################################
# Define some OPerators for coercing MODES #
############################################
OP INITTRIT = (BOOL in)TRIT:
(in|true|false);
OP INITBOOL = (TRIT in)BOOL:
(trit OF in=trit OF true|TRUE|:trit OF in=trit OF false|FALSE|
raise value error(("vague TRIT to BOOL coercion: """, REPR in,""""));~
);
OP B = (TRIT in)BOOL: INITBOOL in;
# These values treated are as per "Balanced ternary" #
# n.b true=1, maybe=0, false=-1 #
# Warning: BOOL ABS FALSE (0) is not the same as TRIT ABS false (-1) #
OP INITINT = (TRIT t)INT:
CASE 1+ABS trit OF t
IN #maybe# 0, #true # 1, #false#-1
OUT raise value error(("invalid TRIT value",REPR t)); ~
ESAC;
OP INITTRIT = (INT in)TRIT: (
TRIT out;
trit OF out:= trit OF
CASE 2+in
IN false, maybe, true
OUT raise value error(("invalid TRIT value",in)); ~
ESAC;
out
);
OP INITTRIT = (BITS b)TRIT:
(TRIT out; trit OF out:=b; out);
##################################################
# Define the LOGICAL OPerators for the TRIT MODE #
##################################################
MODE LOGICAL = TRIT;
PR READ "Template_operators_logical_mixin.a68" PR
COMMENT
Kleene logic truth tables:
END COMMENT
OP AND = (TRIT a,b)TRIT: (
[,]TRIT(
# ∧ ## false, maybe, true #
#false# (false, false, false),
#maybe# (false, maybe, maybe),
#true # (false, maybe, true )
)[@-1,@-1][INITINT a, INITINT b]
);
OP OR = (TRIT a,b)TRIT: (
[,]TRIT(
# ## false, maybe, true #
#false# (false, maybe, true),
#maybe# (maybe, maybe, true),
#true # (true, true, true)
)[@-1,@-1][INITINT a, INITINT b]
);
PRIO IMPLIES = 1; # PRIO = 1.9 #
OP IMPLIES = (TRIT a,b)TRIT: (
[,]TRIT(
# ⊃ ## false, maybe, true #
#false# (true, true, true),
#maybe# (maybe, maybe, true),
#true # (false, maybe, true)
)[@-1,@-1][INITINT a, INITINT b]
);
PRIO EQV = 1; # PRIO = 1.8 #
OP EQV = (TRIT a,b)TRIT: (
[,]TRIT(
# ≡ ## false, maybe, true #
#false# (true, maybe, false),
#maybe# (maybe, maybe, maybe),
#true # (false, maybe, true )
)[@-1,@-1][INITINT a, INITINT b]
);

View file

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*- #
OP & = (LOGICAL a,b)LOGICAL: a AND b;
CO # not included as they are treated as SCALAR #
OP EQ = (LOGICAL a,b)LOGICAL: a = b,
NE = (LOGICAL a,b)LOGICAL: a /= b,
≠ = (TRIT a,b)TRIT: a /= b,
¬= = (TRIT a,b)TRIT: a /= b;
END CO
#IF html entities possible THEN
¢ "parked" operators for completeness ¢
OP ¬ = (LOGICAL a)LOGICAL: NOT a,
∧ = (LOGICAL a,b)LOGICAL: a AND b,
/\ = (LOGICAL a,b)LOGICAL: a AND b,
= (LOGICAL a,b)LOGICAL: a OR b,
\/ = (LOGICAL a,b)LOGICAL: a OR b,
⊃ = (TRIT a,b)TRIT: a IMPLIES b,
≡ = (TRIT a,b)TRIT: a EQV b;
FI#
#IF algol68c THEN
OP ~ = (LOGICAL a)LOGICAL: NOT a,
~= = (LOGICAL a,b)LOGICAL: a /= b; SCALAR!
FI#

View file

@ -0,0 +1,70 @@
#!/usr/local/bin/a68g --script #
# -*- coding: utf-8 -*- #
PR READ "prelude/general.a68" PR
PR READ "Ternary_logic.a68" PR
[]TRIT trits = (false, maybe, true);
FORMAT
col fmt = $" "g" "$,
row fmt = $l3(f(col fmt)"|")f(col fmt)$,
row sep fmt = $l3("---+")"---"l$;
PROC row sep = VOID:
printf(row sep fmt);
PROC title = (STRING op name, LONGCHAR op char)VOID:(
print(("Operator: ",op name));
printf((row fmt,op char,REPR false, REPR maybe, REPR true))
);
PROC print trit op table = (LONGCHAR op char, STRING op name, PROC(TRIT,TRIT)TRIT op)VOID: (
printf($l$);
title(op name, op char);
FOR i FROM LWB trits TO UPB trits DO
row sep;
TRIT ti = trits[i];
printf((col fmt, REPR ti));
FOR j FROM LWB trits TO UPB trits DO
TRIT tj = trits[j];
printf(($"|"$, col fmt, REPR op(ti,tj)))
OD
OD;
printf($l$)
);
printf((
$"Comparitive table of coercions:"l$,
$" TRIT BOOL INT"l$
));
FOR it FROM LWB trits TO UPB trits DO
TRIT t = trits[it];
printf(( $" "g" "$, REPR t,
IF trit OF t = trit OF maybe THEN " " ELSE B t FI,
INITINT t, $l$))
OD;
printf((
$l"Specific test of the IMPLIES operator:"l$,
$" "g" implies "g" is "b("not ","")"a contradiction!"l$,
B false, B false, B(false IMPLIES false),
B false, B true, B(false IMPLIES true),
B false, REPR maybe, B(false IMPLIES maybe),
B true, B false, B(true IMPLIES false),
B true, B true, B(true IMPLIES true),
REPR maybe, Btrue, B(maybe IMPLIES true),
$" "g" implies "g" is "g" a contradiction!"l$,
B true, REPR maybe, REPR (true IMPLIES maybe),
REPR maybe, B false, REPR (maybe IMPLIES false),
REPR maybe, REPR maybe, REPR (maybe IMPLIES maybe),
$l$
));
printf($"Kleene logic truth table samples:"l$);
print trit op table("≡","EQV", (TRIT a,b)TRIT: a EQV 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("","OR", (TRIT a,b)TRIT: a OR b)

View file

@ -0,0 +1,98 @@
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

View file

@ -0,0 +1,15 @@
package Logic is
type Ternary is (True, Unknown, False);
-- logic functions
function "and"(Left, Right: Ternary) return Ternary;
function "or"(Left, Right: Ternary) return Ternary;
function "not"(T: Ternary) return Ternary;
function Equivalent(Left, Right: Ternary) return Ternary;
function Implies(Condition, Conclusion: Ternary) return Ternary;
-- conversion functions
function To_Bool(X: Ternary) return Boolean;
function To_Ternary(B: Boolean) return Ternary;
function Image(Value: Ternary) return Character;
end Logic;

View file

@ -0,0 +1,62 @@
package body Logic is
-- type Ternary is (True, Unknown, False);
function Image(Value: Ternary) return Character is
begin
case Value is
when True => return 'T';
when False => return 'F';
when Unknown => return '?';
end case;
end Image;
function "and"(Left, Right: Ternary) return Ternary is
begin
return Ternary'max(Left, Right);
end "and";
function "or"(Left, Right: Ternary) return Ternary is
begin
return Ternary'min(Left, Right);
end "or";
function "not"(T: Ternary) return Ternary is
begin
case T is
when False => return True;
when Unknown => return Unknown;
when True => return False;
end case;
end "not";
function To_Bool(X: Ternary) return Boolean is
begin
case X is
when True => return True;
when False => return False;
when Unknown => raise Constraint_Error;
end case;
end To_Bool;
function To_Ternary(B: Boolean) return Ternary is
begin
if B then
return True;
else
return False;
end if;
end To_Ternary;
function Equivalent(Left, Right: Ternary) return Ternary is
begin
return To_Ternary(To_Bool(Left) = To_Bool(Right));
exception
when Constraint_Error => return Unknown;
end Equivalent;
function Implies(Condition, Conclusion: Ternary) return Ternary is
begin
return (not Condition) or Conclusion;
end Implies;
end Logic;

View file

@ -0,0 +1,35 @@
with Ada.Text_IO, Logic;
procedure Test_Tri_Logic is
use Logic;
type F2 is access function(Left, Right: Ternary) return Ternary;
type F1 is access function(Trit: Ternary) return Ternary;
procedure Truth_Table(F: F1; Name: String) is
begin
Ada.Text_IO.Put_Line("X | " & Name & "(X)");
for T in Ternary loop
Ada.Text_IO.Put_Line(Image(T) & " | " & Image(F(T)));
end loop;
end Truth_Table;
procedure Truth_Table(F: F2; Name: String) is
begin
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line("X | Y | " & Name & "(X,Y)");
for X in Ternary loop
for Y in Ternary loop
Ada.Text_IO.Put_Line(Image(X) & " | " & Image(Y) & " | " & Image(F(X,Y)));
end loop;
end loop;
end Truth_Table;
begin
Truth_Table(F => "not"'Access, Name => "Not");
Truth_Table(F => "and"'Access, Name => "And");
Truth_Table(F => "or"'Access, Name => "Or");
Truth_Table(F => Equivalent'Access, Name => "Eq");
Truth_Table(F => Implies'Access, Name => "Implies");
end Test_Tri_Logic;

View file

@ -0,0 +1,18 @@
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]
]

View file

@ -0,0 +1,20 @@
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
}

View file

@ -0,0 +1,31 @@
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

View file

@ -0,0 +1,70 @@
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

View file

@ -0,0 +1,46 @@
INSTALL @lib$ + "CLASSLIB"
REM Create a ternary class:
DIM trit{tor, tand, teqv, tnot, tnor, s, v}
DEF PRIVATE trit.s (t&) LOCAL t$():DIM t$(2):t$()="FALSE","MAYBE","TRUE":=t$(t&)
DEF PRIVATE trit.v (t$) = INSTR("FALSE MAYBE TRUE", t$) DIV 6
DEF trit.tnot (t$) = FN(trit.s)(2 - FN(trit.v)(t$))
DEF trit.tor (a$,b$) LOCAL t:t=FN(trit.v)(a$)ORFN(trit.v)(b$):=FN(trit.s)(t+(t>2))
DEF trit.tnor (a$,b$) = FN(trit.tnot)(FN(trit.tor)(a$,b$))
DEF trit.tand (a$,b$) = FN(trit.tnor)(FN(trit.tnot)(a$),FN(trit.tnot)(b$))
DEF trit.teqv (a$,b$) = FN(trit.tor)(FN(trit.tand)(a$,b$),FN(trit.tnor)(a$,b$))
PROC_class(trit{})
PROC_new(mytrit{}, trit{})
REM Test it:
PRINT "Testing NOT:"
PRINT "NOT FALSE = " FN(mytrit.tnot)("FALSE")
PRINT "NOT MAYBE = " FN(mytrit.tnot)("MAYBE")
PRINT "NOT TRUE = " FN(mytrit.tnot)("TRUE")
PRINT '"Testing OR:"
PRINT "FALSE OR FALSE = " FN(mytrit.tor)("FALSE","FALSE")
PRINT "FALSE OR MAYBE = " FN(mytrit.tor)("FALSE","MAYBE")
PRINT "FALSE OR TRUE = " FN(mytrit.tor)("FALSE","TRUE")
PRINT "MAYBE OR MAYBE = " FN(mytrit.tor)("MAYBE","MAYBE")
PRINT "MAYBE OR TRUE = " FN(mytrit.tor)("MAYBE","TRUE")
PRINT "TRUE OR TRUE = " FN(mytrit.tor)("TRUE","TRUE")
PRINT '"Testing AND:"
PRINT "FALSE AND FALSE = " FN(mytrit.tand)("FALSE","FALSE")
PRINT "FALSE AND MAYBE = " FN(mytrit.tand)("FALSE","MAYBE")
PRINT "FALSE AND TRUE = " FN(mytrit.tand)("FALSE","TRUE")
PRINT "MAYBE AND MAYBE = " FN(mytrit.tand)("MAYBE","MAYBE")
PRINT "MAYBE AND TRUE = " FN(mytrit.tand)("MAYBE","TRUE")
PRINT "TRUE AND TRUE = " FN(mytrit.tand)("TRUE","TRUE")
PRINT '"Testing EQV (similar to EOR):"
PRINT "FALSE EQV FALSE = " FN(mytrit.teqv)("FALSE","FALSE")
PRINT "FALSE EQV MAYBE = " FN(mytrit.teqv)("FALSE","MAYBE")
PRINT "FALSE EQV TRUE = " FN(mytrit.teqv)("FALSE","TRUE")
PRINT "MAYBE EQV MAYBE = " FN(mytrit.teqv)("MAYBE","MAYBE")
PRINT "MAYBE EQV TRUE = " FN(mytrit.teqv)("MAYBE","TRUE")
PRINT "TRUE EQV TRUE = " FN(mytrit.teqv)("TRUE","TRUE")
PROC_discard(mytrit{})

View file

@ -0,0 +1,74 @@
#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;
}

View file

@ -0,0 +1,45 @@
using System;
/// <summary>
/// Extension methods on nullable bool.
/// </summary>
/// <remarks>
/// The operators !, & and | are predefined.
/// </remarks>
public static class NullableBoolExtension
{
public static bool? Implies(this bool? left, bool? right)
{
return !left | right;
}
public static bool? IsEquivalentTo(this bool? left, bool? right)
{
return left.HasValue && right.HasValue ? left == right : default(bool?);
}
public static string Format(this bool? value)
{
return value.HasValue ? value.Value.ToString() : "Maybe";
}
}
public class Program
{
private static void Main()
{
var values = new[] { true, default(bool?), false };
foreach (var left in values)
{
Console.WriteLine("¬{0} = {1}", left.Format(), (!left).Format());
foreach (var right in values)
{
Console.WriteLine("{0} & {1} = {2}", left.Format(), right.Format(), (left & right).Format());
Console.WriteLine("{0} | {1} = {2}", left.Format(), right.Format(), (left | right).Format());
Console.WriteLine("{0} → {1} = {2}", left.Format(), right.Format(), left.Implies(right).Format());
Console.WriteLine("{0} ≡ {1} = {2}", left.Format(), right.Format(), left.IsEquivalentTo(right).Format());
}
}
}
}

View file

@ -0,0 +1,71 @@
#include <stdio.h>
typedef enum {
TRITTRUE, /* In this enum, equivalent to integer value 0 */
TRITMAYBE, /* In this enum, equivalent to integer value 1 */
TRITFALSE /* In this enum, equivalent to integer value 2 */
} trit;
/* We can trivially find the result of the operation by passing
the trinary values as indeces into the lookup tables' arrays. */
trit tritNot[3] = {TRITFALSE , TRITMAYBE, TRITTRUE};
trit tritAnd[3][3] = { {TRITTRUE, TRITMAYBE, TRITFALSE},
{TRITMAYBE, TRITMAYBE, TRITFALSE},
{TRITFALSE, TRITFALSE, TRITFALSE} };
trit tritOr[3][3] = { {TRITTRUE, TRITTRUE, TRITTRUE},
{TRITTRUE, TRITMAYBE, TRITMAYBE},
{TRITTRUE, TRITMAYBE, TRITFALSE} };
trit tritThen[3][3] = { { TRITTRUE, TRITMAYBE, TRITFALSE},
{ TRITTRUE, TRITMAYBE, TRITMAYBE},
{ TRITTRUE, TRITTRUE, TRITTRUE } };
trit tritEquiv[3][3] = { { TRITTRUE, TRITMAYBE, TRITFALSE},
{ TRITMAYBE, TRITMAYBE, TRITMAYBE},
{ TRITFALSE, TRITMAYBE, TRITTRUE } };
/* Everything beyond here is just demonstration */
const char* tritString[3] = {"T", "?", "F"};
void demo_binary_op(trit operator[3][3], const char* name)
{
trit operand1 = TRITTRUE; /* Declare. Initialize for CYA */
trit operand2 = TRITTRUE; /* Declare. Initialize for CYA */
/* Blank line */
printf("\n");
/* Demo this operator */
for( operand1 = TRITTRUE; operand1 <= TRITFALSE; ++operand1 )
{
for( operand2 = TRITTRUE; operand2 <= TRITFALSE; ++operand2 )
{
printf("%s %s %s: %s\n", tritString[operand1],
name,
tritString[operand2],
tritString[operator[operand1][operand2]]);
}
}
}
int main()
{
trit op1 = TRITTRUE; /* Declare. Initialize for CYA */
trit op2 = TRITTRUE; /* Declare. Initialize for CYA */
/* Demo 'not' */
for( op1 = TRITTRUE; op1 <= TRITFALSE; ++op1 )
{
printf("Not %s: %s\n", tritString[op1], tritString[tritNot[op1]]);
}
demo_binary_op(tritAnd, "And");
demo_binary_op(tritOr, "Or");
demo_binary_op(tritThen, "Then");
demo_binary_op(tritEquiv, "Equiv");
return 0;
}

View file

@ -0,0 +1,36 @@
#include <stdio.h>
typedef enum { t_F = -1, t_M, t_T } trit;
trit t_not (trit a) { return -a; }
trit t_and (trit a, trit b) { return a < b ? a : b; }
trit t_or (trit a, trit b) { return a > b ? a : b; }
trit t_eq (trit a, trit b) { return a * b; }
trit t_imply(trit a, trit b) { return -a > b ? -a : b; }
char t_s(trit a) { return "F?T"[a + 1]; }
#define forall(a) for(a = t_F; a <= t_T; a++)
void show_op(trit (*f)(trit, trit), const char *name) {
trit a, b;
printf("\n[%s]\n F ? T\n -------", name);
forall(a) {
printf("\n%c |", t_s(a));
forall(b) printf(" %c", t_s(f(a, b)));
}
puts("");
}
int main(void)
{
trit a;
puts("[Not]");
forall(a) printf("%c | %c\n", t_s(a), t_s(t_not(a)));
show_op(t_and, "And");
show_op(t_or, "Or");
show_op(t_eq, "Equiv");
show_op(t_imply, "Imply");
return 0;
}

View file

@ -0,0 +1,55 @@
#include <stdio.h>
#include <stdlib.h>
typedef double half_truth, maybe;
inline maybe not3(maybe a) { return 1 - a; }
inline maybe
and3(maybe a, maybe b) { return a * b; }
inline maybe
or3(maybe a, maybe b) { return a + b - a * b; }
inline maybe
eq3(maybe a, maybe b) { return 1 - a - b + 2 * a * b; }
inline maybe
imply3(maybe a, maybe b) { return or3(not3(a), b); }
#define true3(x) ((x) * RAND_MAX > rand())
#define if3(x) if (true3(x))
int main()
{
maybe roses_are_red = 0.25; /* they can be white or black, too */
maybe violets_are_blue = 1; /* aren't they just */
int i;
puts("Verifying flowery truth for 40 times:\n");
puts("Rose is NOT red:"); /* chance: .75 */
for (i = 0; i < 40 || !puts("\n"); i++)
printf( true3( not3(roses_are_red) ) ? "T" : "_");
/* pick a rose and a violet; */
puts("Rose is red AND violet is blue:");
/* chance of rose being red AND violet being blue is .25 */
for (i = 0; i < 40 || !puts("\n"); i++)
printf( true3( and3(roses_are_red, violets_are_blue) )
? "T" : "_");
/* chance of rose being red OR violet being blue is 1 */
puts("Rose is red OR violet is blue:");
for (i = 0; i < 40 || !puts("\n"); i++)
printf( true3( or3(roses_are_red, violets_are_blue) )
? "T" : "_");
/* pick two roses; chance of em being both red or both not red is .625 */
puts("This rose is as red as that rose:");
for (i = 0; i < 40 || !puts("\n"); i++)
if3(eq3(roses_are_red, roses_are_red)) putchar('T');
else putchar('_');
return 0;
}

View file

@ -0,0 +1,31 @@
(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))))
(defun tri-eq (x y) (+ (tri-and x y) (tri-and (- 1 x) (- 1 y))))
(defun tri-imply (x y) (tri-or (tri-not x) y))
(defun tri-test (x) (< (random 1e0) x))
(defun tri-string (x) (if (= x 1) "T" (if (= x 0) "F" "?")))
;; to say (tri-if (condition) (yes) (no))
(defmacro tri-if (tri ifcase &optional elsecase)
`(if (tri-test ,tri) ,ifcase ,elsecase))
(defun print-table (func header)
(let ((vals '(1 .5 0)))
(format t "~%~a:~%" header)
(format t " ~{~a ~^~}~%---------~%" (mapcar #'tri-string vals))
(loop for row in vals do
(format t "~a | " (tri-string row))
(loop for col in vals do
(format t "~a " (tri-string (funcall func row col))))
(write-line ""))))
(write-line "NOT:")
(loop for row in '(1 .5 0) do
(format t "~a | ~a~%" (tri-string row) (tri-string (tri-not row))))
(print-table #'tri-and "AND")
(print-table #'tri-or "OR")
(print-table #'tri-imply "IMPLY")
(print-table #'tri-eq "EQUAL")

View file

@ -0,0 +1,68 @@
import std.stdio;
struct Trit {
private enum Val : byte { F = -1, M, T }
private Val t;
alias t this;
static immutable Trit[3] vals = [{Val.F}, {Val.M}, {Val.T}];
static immutable F = Trit(Val.F); // Not necessary but handy.
static immutable M = Trit(Val.M);
static immutable T = Trit(Val.T);
string toString() const pure nothrow {
return "F?T"[t + 1 .. t + 2];
}
Trit opUnary(string op)() const pure nothrow
if (op == "~") {
return Trit(-t);
}
Trit opBinary(string op)(in Trit b) const pure nothrow
if (op == "&") {
return t < b ? this : b;
}
Trit opBinary(string op)(in Trit b) const pure nothrow
if (op == "|") {
return t > b ? this : b;
}
Trit opBinary(string op)(in Trit b) const pure nothrow
if (op == "^") {
return ~(this == b);
}
Trit opEquals(in Trit b) const pure nothrow {
return Trit(cast(Val)(t * b));
}
Trit imply(in Trit b) const pure nothrow {
return -t > b ? ~this : b;
}
}
void showOperation(string op)(in string opName) {
writef("\n[%s]\n F ? T\n -------", opName);
foreach (immutable a; Trit.vals) {
writef("\n%s |", a);
foreach (immutable b; Trit.vals)
static if (op == "==>")
writef(" %s", a.imply(b));
else
writef(" %s", mixin("a " ~ op ~ " b"));
}
writeln();
}
void main() {
writeln("[Not]");
foreach (const a; Trit.vals)
writefln("%s | %s", a, ~a);
showOperation!"&"("And");
showOperation!"|"("Or");
showOperation!"^"("Xor");
showOperation!"=="("Equiv");
showOperation!"==>"("Imply");
}

View file

@ -0,0 +1,56 @@
unit TrinaryLogic;
interface
//Define our own type for ternary logic.
//This is actually still a Boolean, but the compiler will use distinct RTTI information.
type
TriBool = type Boolean;
const
TTrue:TriBool = True;
TFalse:TriBool = False;
TMaybe:TriBool = TriBool(2);
function TVL_not(Value: TriBool): TriBool;
function TVL_and(A, B: TriBool): TriBool;
function TVL_or(A, B: TriBool): TriBool;
function TVL_xor(A, B: TriBool): TriBool;
function TVL_eq(A, B: TriBool): TriBool;
implementation
Uses
SysUtils;
function TVL_not(Value: TriBool): TriBool;
begin
if Value = True Then
Result := TFalse
else If Value = False Then
Result := TTrue
else
Result := Value;
end;
function TVL_and(A, B: TriBool): TriBool;
begin
Result := TriBool(Iff(Integer(A * B) > 1, Integer(TMaybe), A * B));
end;
function TVL_or(A, B: TriBool): TriBool;
begin
Result := TVL_not(TVL_and(TVL_not(A), TVL_not(B)));
end;
function TVL_xor(A, B: TriBool): TriBool;
begin
Result := TVL_and(TVL_or(A, B), TVL_not(TVL_or(A, B)));
end;
function TVL_eq(A, B: TriBool): TriBool;
begin
Result := TVL_not(TVL_xor(A, B));
end;
end.

View file

@ -0,0 +1 @@
type TriBool = (tbFalse, tbMaybe, tbTrue);

View file

@ -0,0 +1,22 @@
const
tvl_not: array[TriBool] = (tbTrue, tbMaybe, tbFalse);
tvl_and: array[TriBool, TriBool] = (
(tbFalse, tbFalse, tbFalse),
(tbFalse, tbMaybe, tbMaybe),
(tbFalse, tbMaybe, tbTrue),
);
tvl_or: array[TriBool, TriBool] = (
(tbFalse, tbMaybe, tbTrue),
(tbMaybe, tbMaybe, tbTrue),
(tbTrue, tbTrue, tbTrue),
);
tvl_xor: array[TriBool, TriBool] = (
(tbFalse, tbMaybe, tbTrue),
(tbMaybe, tbMaybe, tbMaybe),
(tbTrue, tbMaybe, tbFalse),
);
tvl_eq: array[TriBool, TriBool] = (
(tbTrue, tbMaybe, tbFalse),
(tbMaybe, tbMaybe, tbMaybe),
(tbFalse, tbMaybe, tbTrue),
);

View file

@ -0,0 +1 @@
Result := tvl_and[A, B];

View file

@ -0,0 +1,69 @@
import extensions;
import system'routines;
import system'collections;
sealed class Trit
{
bool _value;
bool cast() = _value;
constructor(v)
{
if (v != nil)
{
_value := cast bool(v);
}
}
Trit equivalent(b)
= _value.equal(cast bool(b)) \ back:nilValue;
Trit Inverted
= _value.Inverted \ back:nilValue;
Trit and(b)
{
if (nil == _value)
{
^ b.and:nil \ back:nilValue
}
else
{
^ _value.and((lazy:cast bool(b))) \ back:nilValue
}
}
Trit or(b)
{
if (nil == _value)
{
^ b.or:nilValue \ back:nilValue
}
else
{
^ _value.or((lazy:cast bool(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)
}
}
}

View file

@ -0,0 +1,74 @@
% 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.

View file

@ -0,0 +1,41 @@
! rosettacode/ternary/ternary.factor
! http://rosettacode.org/wiki/Ternary_logic
USING: combinators kernel ;
IN: rosettacode.ternary
SINGLETON: m
UNION: trit t m POSTPONE: f ;
GENERIC: >trit ( object -- trit )
M: trit >trit ;
: tnot ( trit1 -- trit )
>trit { { t [ f ] } { m [ m ] } { f [ t ] } } case ;
: tand ( trit1 trit2 -- trit )
>trit {
{ t [ >trit ] }
{ m [ >trit { { t [ m ] } { m [ m ] } { f [ f ] } } case ] }
{ f [ >trit drop f ] }
} case ;
: tor ( trit1 trit2 -- trit )
>trit {
{ t [ >trit drop t ] }
{ m [ >trit { { t [ t ] } { m [ m ] } { f [ m ] } } case ] }
{ f [ >trit ] }
} case ;
: txor ( trit1 trit2 -- trit )
>trit {
{ t [ tnot ] }
{ m [ >trit drop m ] }
{ f [ >trit ] }
} case ;
: t= ( trit1 trit2 -- trit )
{
{ t [ >trit ] }
{ m [ >trit drop m ] }
{ f [ tnot ] }
} case ;

View file

@ -0,0 +1,11 @@
( scratchpad ) CONSTANT: trits { t m f }
( scratchpad ) trits [ tnot ] map .
{ f m t }
( scratchpad ) trits [ trits swap [ tand ] curry map ] map .
{ { t m f } { m m f } { f f f } }
( scratchpad ) trits [ trits swap [ tor ] curry map ] map .
{ { t t t } { t m m } { t m f } }
( scratchpad ) trits [ trits swap [ txor ] curry map ] map .
{ { 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 } }

View file

@ -0,0 +1,33 @@
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

View file

@ -0,0 +1,97 @@
!-*- 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

View file

@ -0,0 +1,66 @@
{$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.

View file

@ -0,0 +1,46 @@
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.

View file

@ -0,0 +1,45 @@
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

View file

@ -0,0 +1,75 @@
package main
import "fmt"
type trit int8
const (
trFalse trit = iota - 1
trMaybe
trTrue
)
func (t trit) String() string {
switch t {
case trFalse:
return "False"
case trMaybe:
return "Maybe"
case trTrue:
return "True "
}
panic("Invalid trit")
}
func trNot(t trit) trit {
return -t
}
func trAnd(s, t trit) trit {
if s < t {
return s
}
return t
}
func trOr(s, t trit) trit {
if s > t {
return s
}
return t
}
func trEq(s, t trit) trit {
return s * t
}
func main() {
trSet := []trit{trFalse, trMaybe, trTrue}
fmt.Println("t not t")
for _, t := range trSet {
fmt.Println(t, trNot(t))
}
fmt.Println("\ns t s and t")
for _, s := range trSet {
for _, t := range trSet {
fmt.Println(s, t, trAnd(s, t))
}
}
fmt.Println("\ns t s or t")
for _, s := range trSet {
for _, t := range trSet {
fmt.Println(s, t, trOr(s, t))
}
}
fmt.Println("\ns t s eq t")
for _, s := range trSet {
for _, t := range trSet {
fmt.Println(s, t, trEq(s, t))
}
}
}

View file

@ -0,0 +1,18 @@
enum Trit {
TRUE, MAYBE, FALSE
private Trit nand(Trit that) {
switch ([this,that]) {
case { FALSE in it }: return TRUE
case { MAYBE in it }: return MAYBE
default : return FALSE
}
}
private Trit nor(Trit that) { this.or(that).not() }
Trit and(Trit that) { this.nand(that).not() }
Trit or(Trit that) { this.not().nand(that.not()) }
Trit not() { this.nand(this) }
Trit imply(Trit that) { this.nand(that.not()) }
Trit equiv(Trit that) { this.and(that).or(this.nor(that)) }
}

View file

@ -0,0 +1,40 @@
printf 'AND\n '
Trit.values().each { b -> printf ('%6s', b) }
println '\n ----- ----- -----'
Trit.values().each { a ->
printf ('%6s | ', a)
Trit.values().each { b -> printf ('%6s', a.and(b)) }
println()
}
printf '\nOR\n '
Trit.values().each { b -> printf ('%6s', b) }
println '\n ----- ----- -----'
Trit.values().each { a ->
printf ('%6s | ', a)
Trit.values().each { b -> printf ('%6s', a.or(b)) }
println()
}
println '\nNOT'
Trit.values().each {
printf ('%6s | %6s\n', it, it.not())
}
printf '\nIMPLY\n '
Trit.values().each { b -> printf ('%6s', b) }
println '\n ----- ----- -----'
Trit.values().each { a ->
printf ('%6s | ', a)
Trit.values().each { b -> printf ('%6s', a.imply(b)) }
println()
}
printf '\nEQUIV\n '
Trit.values().each { b -> printf ('%6s', b) }
println '\n ----- ----- -----'
Trit.values().each { a ->
printf ('%6s | ', a)
Trit.values().each { b -> printf ('%6s', a.equiv(b)) }
println()
}

View file

@ -0,0 +1,37 @@
import Prelude hiding (Bool(..), not, (&&), (||), (==))
main = mapM_ (putStrLn . unlines . map unwords)
[ table "not" $ unary not
, table "and" $ binary (&&)
, table "or" $ binary (||)
, table "implies" $ binary (=->)
, table "equals" $ binary (==)
]
data Trit = False | Maybe | True deriving (Show)
False `nand` _ = True
_ `nand` False = True
True `nand` True = False
_ `nand` _ = Maybe
not a = nand a a
a && b = not $ a `nand` b
a || b = not a `nand` not b
a =-> b = a `nand` not b
a == b = (a && b) || (not a && not b)
inputs1 = [True, Maybe, False]
inputs2 = [(a,b) | a <- inputs1, b <- inputs1]
unary f = map (\a -> [a, f a]) inputs1
binary f = map (\(a,b) -> [a, b, f a b]) inputs2
table name xs = map (map pad) . (header :) $ map (map show) xs
where header = map (:[]) (take ((length $ head xs) - 1) ['A'..]) ++ [name]
pad s = s ++ replicate (5 - length s) ' '

View file

@ -0,0 +1,62 @@
$define TRUE 1
$define FALSE -1
$define UNKNOWN 0
invocable all
link printf
procedure main() # demonstrate ternary logic
ufunc := ["not3"]
bfunc := ["and3", "or3", "xor3", "eq3", "ifthen3"]
every f := !ufunc do { # display unary functions
printf("\nunary function=%s:\n",f)
every t1 := (TRUE | FALSE | UNKNOWN) do
printf(" %s : %s\n",showtrit(t1),showtrit(not3(t1)))
}
every f := !bfunc do { # display binary functions
printf("\nbinary function=%s:\n ",f)
every t1 := (&null | TRUE | FALSE | UNKNOWN) do {
printf(" %s : ",showtrit(\t1))
every t2 := (TRUE | FALSE | UNKNOWN | &null) do {
if /t1 then printf(" %s",showtrit(\t2)|"\n")
else printf(" %s",showtrit(f(t1,\t2))|"\n")
}
}
}
end
procedure showtrit(a) #: return printable trit of error if invalid
return case a of {TRUE:"T";FALSE:"F";UNKNOWN:"?";default:runerr(205,a)}
end
procedure istrit(a) #: return value of trit or error if invalid
return (TRUE|FALSE|UNKNOWN|runerr(205,a)) = a
end
procedure not3(a) #: not of trit or error if invalid
return FALSE * istrit(a)
end
procedure and3(a,b) #: and of two trits or error if invalid
return min(istrit(a),istrit(b))
end
procedure or3(a,b) #: or of two trits or error if invalid
return max(istrit(a),istrit(b))
end
procedure eq3(a,b) #: equals of two trits or error if invalid
return istrit(a) * istrit(b)
end
procedure ifthen3(a,b) #: if trit then trit or error if invalid
return case istrit(a) of { TRUE: istrit(b) ; UNKNOWN: or3(a,b); FALSE: TRUE }
end
procedure xor3(a,b) #: xor of two trits or error if invalid
return not3(eq3(a,b))
end

View file

@ -0,0 +1,5 @@
not=: -.
and=: <.
or =: >.
if =: (>. -.)"0~
eq =: (<.&-. >. <.)"0

View file

@ -0,0 +1,22 @@
not 0 0.5 1
1 0.5 0
0 0.5 1 and/ 0 0.5 1
0 0 0
0 0.5 0.5
0 0.5 1
0 0.5 1 or/ 0 0.5 1
0 0.5 1
0.5 0.5 1
1 1 1
0 0.5 1 if/ 0 0.5 1
1 1 1
0.5 0.5 1
0 0.5 1
0 0.5 1 eq/ 0 0.5 1
1 0.5 0
0.5 0.5 0.5
0 0.5 1

View file

@ -0,0 +1,5 @@
not=: -.
and=: *
or=: *&.-.
if =: (or -.)"0~
eq =: (*&-. or *)"0

View file

@ -0,0 +1,22 @@
not 0 0.5 1
1 0.5 0
0 0.5 1 and/ 0 0.5 1
0 0 0
0 0.25 0.5
0 0.5 1
0 0.5 1 or/ 0 0.5 1
0 0.5 1
0.5 0.75 1
1 1 1
0 0.5 1 if/ 0 0.5 1
1 1 1
0.5 0.75 1
0 0.5 1
0 0.5 1 eq/ 0 0.5 1
1 0.5 0
0.5 0.4375 0.5
0 0.5 1

View file

@ -0,0 +1,2 @@
and=: *.
or=: +.

View file

@ -0,0 +1,9 @@
0 0.5 1 and/ 0 0.5 1
0 0 0
0 0.5 1
0 1 1
0 0.5 1 or/ 0 0.5 1
0 0.5 1
0.5 0.5 0.5
1 0.5 1

View file

@ -0,0 +1,68 @@
public class Logic{
public static enum Trit{
TRUE, MAYBE, FALSE;
public Trit and(Trit other){
if(this == TRUE){
return other;
}else if(this == MAYBE){
return (other == FALSE) ? FALSE : MAYBE;
}else{
return FALSE;
}
}
public Trit or(Trit other){
if(this == TRUE){
return TRUE;
}else if(this == MAYBE){
return (other == TRUE) ? TRUE : MAYBE;
}else{
return other;
}
}
public Trit tIf(Trit other){
if(this == TRUE){
return other;
}else if(this == MAYBE){
return (other == TRUE) ? TRUE : MAYBE;
}else{
return TRUE;
}
}
public Trit not(){
if(this == TRUE){
return FALSE;
}else if(this == MAYBE){
return MAYBE;
}else{
return TRUE;
}
}
public Trit equals(Trit other){
if(this == TRUE){
return other;
}else if(this == MAYBE){
return MAYBE;
}else{
return other.not();
}
}
}
public static void main(String[] args){
for(Trit a:Trit.values()){
System.out.println("not " + a + ": " + a.not());
}
for(Trit a:Trit.values()){
for(Trit b:Trit.values()){
System.out.println(a+" and "+b+": "+a.and(b)+
"\t "+a+" or "+b+": "+a.or(b)+
"\t "+a+" implies "+b+": "+a.tIf(b)+
"\t "+a+" = "+b+": "+a.equals(b));
}
}
}
}

View file

@ -0,0 +1,33 @@
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));
}

View file

@ -0,0 +1,10 @@
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

View file

@ -0,0 +1,9 @@
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
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))

View file

@ -0,0 +1,15 @@
functor = {nand, and, or, nor, implies, iff, xor}
display = {nand: '⊼', and: '∧', or: '', nor: '⊽', implies: '⇒', iff: '⇔', xor: '⊻', not: '¬'}
values = Object.values(trit)
log = 'NOT\n';
for (let a of values) log += `${display.not}${a} = ${a}\n`
log += '\nNAND AND OR NOR IMPLIES IFF XOR'
for (let a of values) {
for (let b of values) {
log += "\n"
for (let op in functor) log += `${a} ${display[op]} ${b} = ${functor[op](a, b)} `
}
}
console.log(log)

View file

@ -0,0 +1,15 @@
NOT
¬F = F
¬U = U
¬T = T
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 U = T F U = F F U = U F U = U F U = T F U = U F U = U
F T = T F T = F F T = T F T = F F T = T F T = F F T = T
U F = T U F = F U F = U U F = U U F = U U F = U U F = U
U U = U U U = U U U = U U U = U U U = U U U = U U U = U
U T = U U T = U U T = T U T = F U T = T U T = U U T = U
T F = T T F = F T F = T T F = F T F = F T F = F T F = T
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

View file

@ -0,0 +1,32 @@
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"

View file

@ -0,0 +1,27 @@
@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

View file

@ -0,0 +1,32 @@
# 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

View file

@ -0,0 +1,86 @@
// 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()
}
}

View file

@ -0,0 +1,56 @@
# borrowing null for "maybe"
val .trSet = [false, null, true]
val .and = f given .a, .b {
case true, null:
case null, true:
case null: null
default: .a and .b
}
val .or = f given .a, .b {
case false, null:
case null, false:
case null: null
default: .a or .b
}
val .imply = f 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 = f $"\{nn [.r, "maybe"]:-5}"
writeln "a not a"
for .a in .trSet {
writeln $"\.a:.F; \(not? .a:.F)"
}
writeln "\na b a and b"
for .a in .trSet {
for .b in .trSet {
writeln $"\.a:.F; \.b:.F; \.and(.a, .b):.F;"
}
}
writeln "\na b a or b"
for .a in .trSet {
for .b in .trSet {
writeln $"\.a:.F; \.b:.F; \.or(.a, .b):.F;"
}
}
writeln "\na b a implies b"
for .a in .trSet {
for .b in .trSet {
writeln $"\.a:.F; \.b:.F; \.imply(.a, .b):.F;"
}
}
writeln "\na b a eq b"
for .a in .trSet {
for .b in .trSet {
writeln $"\.a:.F; \.b:.F; \.a ==? .b:.F;"
}
}

View file

@ -0,0 +1,70 @@
'ternary logic
'0 1 2
'F ? T
'False Don't know True
'LB has NOT AND OR XOR, so we implement them.
'LB has no EQ, but XOR could be expressed via EQ. In 'normal' boolean at least.
global tFalse, tDontKnow, tTrue
tFalse = 0
tDontKnow = 1
tTrue = 2
print "Short and long names for ternary logic values"
for i = tFalse to tTrue
print shortName3$(i);" ";longName3$(i)
next
print
print "Single parameter functions"
print "x";" ";"=x";" ";"not(x)"
for i = tFalse to tTrue
print shortName3$(i);" ";shortName3$(i);" ";shortName3$(not3(i))
next
print
print "Double parameter fuctions"
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);" "; _
shortName3$(and3(a,b));" "; shortName3$(or3(a,b));" "; _
shortName3$(eq3(a,b));" "; shortName3$(xor3(a,b))
next
next
function and3(a,b)
and3 = min(a,b)
end function
function or3(a,b)
or3 = max(a,b)
end function
function eq3(a,b)
select case
case a=tDontKnow or b=tDontKnow
eq3 = tDontKnow
case a=b
eq3 = tTrue
case else
eq3 = tFalse
end select
end function
function xor3(a,b)
xor3 = not3(eq3(a,b))
end function
function not3(b)
not3 = 2-b
end function
'------------------------------------------------
function shortName3$(i)
shortName3$ = word$("F ? T", i+1)
end function
function longName3$(i)
longName3$ = word$("False,Don't know,True", i+1, ",")
end function

View file

@ -0,0 +1,160 @@
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

View file

@ -0,0 +1,6 @@
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] );

View file

@ -0,0 +1,33 @@
> 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]

View file

@ -0,0 +1,2 @@
Maybe /: ! Maybe = Maybe;
Maybe /: (And | Or | Nand | Nor | Xor | Xnor | Implies | Equivalent)[Maybe, Maybe] = Maybe;

View file

@ -0,0 +1,9 @@
trits = {True, Maybe, False};
Print@Grid[
ArrayFlatten[{{{{Not}}, {{Null}}}, {List /@ trits,
List /@ Not /@ trits}}]];
Do[Print@Grid[
ArrayFlatten[{{{{operator}}, {{Null, Null,
Null}}}, {{{Null}}, {trits}}, {List /@ trits,
Outer[operator, trits, trits]}}]], {operator, {And, Or, Nand,
Nor, Xor, Xnor, Implies, Equivalent}}]

View file

@ -0,0 +1,56 @@
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)

View file

@ -0,0 +1,44 @@
type trit = True | False | Maybe
let t_not = function
| True -> False
| False -> True
| Maybe -> Maybe
let t_and a b = match (a,b) with
| (True,True) -> True
| (False,_) | (_,False) -> False
| _ -> Maybe
let t_or a b = t_not (t_and (t_not a) (t_not b))
let t_eq a b = match (a,b) with
| (True,True) | (False,False) -> True
| (False,True) | (True,False) -> False
| _ -> Maybe
let t_imply a b = t_or (t_not a) b
let string_of_trit = function
| True -> "True"
| False -> "False"
| Maybe -> "Maybe"
let () =
let values = [| True; Maybe; False |] in
let f = string_of_trit in
Array.iter (fun v -> Printf.printf "Not %s: %s\n" (f v) (f (t_not v))) values;
print_newline ();
let print op str =
Array.iter (fun a ->
Array.iter (fun b ->
Printf.printf "%s %s %s: %s\n" (f a) str (f b) (f (op a b))
) values
) values;
print_newline ()
in
print t_and "And";
print t_or "Or";
print t_imply "Then";
print t_eq "Equiv";
;;

View file

@ -0,0 +1,40 @@
type trit = True | False | Maybe
let to_bin = function True -> [true] | False -> [false] | Maybe -> [true;false]
let eval f x =
List.fold_left (fun l c -> List.fold_left (fun m d -> ((d c) :: m)) l f) [] x
let rec from_bin =
function [true] -> True | [false] -> False
| h :: t -> (match (h, from_bin t) with
(true,True) -> True | (false,False) -> False | _ -> Maybe)
| _ -> Maybe
let to_ternary1 uop = fun x -> from_bin (eval [uop] (to_bin x))
let to_ternary2 bop = fun x y -> from_bin (eval (eval [bop] (to_bin x)) (to_bin y))
let t_not = to_ternary1 (not)
let t_and = to_ternary2 (&&)
let t_or = to_ternary2 (||)
let t_equiv = to_ternary2 (=)
let t_imply = to_ternary2 (fun p q -> (not p) || q)
let str = function True -> "True " | False -> "False" | Maybe -> "Maybe"
let iterv f = List.iter f [True; False; Maybe]
let table1 s u =
print_endline ("\n"^s^":");
iterv (fun v -> print_endline (" "^(str v)^" -> "^(str (u v))));;
let table2 s b =
print_endline ("\n"^s^":");
iterv (fun u ->
iterv (fun v ->
print_endline (" "^(str u)^" "^(str v)^" -> "^(str (b u v)))));;
table1 "not" t_not;;
table2 "and" t_and;;
table2 "or" t_or;;
table2 "equiv" t_equiv;;
table2 "implies" t_imply;;

View file

@ -0,0 +1,124 @@
tritValues = .array~of(.trit~true, .trit~false, .trit~maybe)
tab = '09'x
say "not operation (\)"
loop a over tritValues
say "\"a":" (\a)
end
say
say "and operation (&)"
loop aa over tritValues
loop bb over tritValues
say (aa" & "bb":" (aa&bb))
end
end
say
say "or operation (|)"
loop aa over tritValues
loop bb over tritValues
say (aa" | "bb":" (aa|bb))
end
end
say
say "implies operation (&&)"
loop aa over tritValues
loop bb over tritValues
say (aa" && "bb":" (aa&&bb))
end
end
say
say "equals operation (=)"
loop aa over tritValues
loop bb over tritValues
say (aa" = "bb":" (aa=bb))
end
end
::class trit
-- making this a private method so we can control the creation
-- of these. We only allow 3 instances to exist
::method new class private
forward class(super)
::method init class
expose true false maybe
-- delayed creation
true = .nil
false = .nil
maybe = .nil
-- read only attribute access to the instances.
-- these methods create the appropriate singleton on the first call
::attribute true class get
expose true
if true == .nil then true = self~new("True")
return true
::attribute false class get
expose false
if false == .nil then false = self~new("False")
return false
::attribute maybe class get
expose maybe
if maybe == .nil then maybe = self~new("Maybe")
return maybe
-- create an instance
::method init
expose value
use arg value
-- string method to return the value of the instance
::method string
expose value
return value
-- "and" method using the operator overload
::method "&"
use strict arg other
if self == .trit~true then return other
else if self == .trit~maybe then do
if other == .trit~false then return .trit~false
else return .trit~maybe
end
else return .trit~false
-- "or" method using the operator overload
::method "|"
use strict arg other
if self == .trit~true then return .trit~true
else if self == .trit~maybe then do
if other == .trit~true then return .trit~true
else return .trit~maybe
end
else return other
-- implies method...using the XOR operator for this
::method "&&"
use strict arg other
if self == .trit~true then return other
else if self == .trit~maybe then do
if other == .trit~true then return .trit~true
else return .trit~maybe
end
else return .trit~true
-- "not" method using the operator overload
::method "\"
if self == .trit~true then return .trit~false
else if self == .trit~maybe then return .trit~maybe
else return .trit~true
-- "equals" using the "=" override. This makes a distinction between
-- the "==" operator, which is real equality and the "=" operator, which
-- is trinary equality.
::method "="
use strict arg other
if self == .trit~true then return other
else if self == .trit~maybe then return .trit~maybe
else return \other

View file

@ -0,0 +1,61 @@
#!/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() {
if (func_num_args() < 2)
trigger_error('triAnd needs 2 or more parameters', E_USER_ERROR);
return min(func_get_args());
}
function triOr() {
if (func_num_args() < 2)
trigger_error('triOr needs 2 or more parameters', E_USER_ERROR);
return max(func_get_args());
}
function triNot($t) {
global $triNotarray; # using result table
if (in_array($t, $triNotarray)) return $triNotarray[$t];
trigger_error('triNot: Parameter is not a tri value', E_USER_ERROR);
}
function triImplies($a, $b) {
if ($a===triFalse || $b===triTrue) return triTrue;
if ($a===triMaybe || $b===triMaybe) return triMaybe;
# without parameter type check I just would return triFalse here
if ($a===triTrue && $b===triFalse) return triFalse;
trigger_error('triImplies: parameter type error', E_USER_ERROR);
}
function triEquiv($a, $b) {
if ($a===triTrue) return $b;
if ($a===triMaybe) return $a;
if ($a===triFalse) return triNot($b);
trigger_error('triEquiv: parameter type error', E_USER_ERROR);
}
# data sampling
printf("--- Sample output for a equivalent b ---\n\n");
foreach ([triTrue,triMaybe,triFalse] as $a) {
foreach ([triTrue,triMaybe,triFalse] as $b) {
printf("for a=%s and b=%s a equivalent b is %s\n",
triString($a), triString($b), triString(triEquiv($a, $b)));
}
}

View file

@ -0,0 +1,91 @@
Program TernaryLogic (output);
type
trit = (terTrue, terMayBe, terFalse);
function terNot (a: trit): trit;
begin
case a of
terTrue: terNot := terFalse;
terMayBe: terNot := terMayBe;
terFalse: terNot := terTrue;
end;
end;
function terAnd (a, b: trit): trit;
begin
terAnd := terMayBe;
if (a = terFalse) or (b = terFalse) then
terAnd := terFalse
else
if (a = terTrue) and (b = terTrue) then
terAnd := terTrue;
end;
function terOr (a, b: trit): trit;
begin
terOr := terMayBe;
if (a = terTrue) or (b = terTrue) then
terOr := terTrue
else
if (a = terFalse) and (b = terFalse) then
terOr := terFalse;
end;
function terEquals (a, b: trit): trit;
begin
if a = b then
terEquals := terTrue
else
if a <> b then
terEquals := terFalse;
if (a = terMayBe) or (b = terMayBe) then
terEquals := terMayBe;
end;
function terIfThen (a, b: trit): trit;
begin
terIfThen := terMayBe;
if (a = terTrue) or (b = terFalse) then
terIfThen := terTrue
else
if (a = terFalse) and (b = terTrue) then
terIfThen := terFalse;
end;
function terToStr(a: trit): string;
begin
case a of
terTrue: terToStr := 'True ';
terMayBe: terToStr := 'Maybe';
terFalse: terToStr := 'False';
end;
end;
begin
writeln('Ternary logic test:');
writeln;
writeln('NOT ', ' True ', ' Maybe', ' False');
writeln(' ', terToStr(terNot(terTrue)), ' ', terToStr(terNot(terMayBe)), ' ', terToStr(terNot(terFalse)));
writeln;
writeln('AND ', ' True ', ' Maybe', ' False');
writeln('True ', terToStr(terAnd(terTrue,terTrue)), ' ', terToStr(terAnd(terMayBe,terTrue)), ' ', terToStr(terAnd(terFalse,terTrue)));
writeln('Maybe ', terToStr(terAnd(terTrue,terMayBe)), ' ', terToStr(terAnd(terMayBe,terMayBe)), ' ', terToStr(terAnd(terFalse,terMayBe)));
writeln('False ', terToStr(terAnd(terTrue,terFalse)), ' ', terToStr(terAnd(terMayBe,terFalse)), ' ', terToStr(terAnd(terFalse,terFalse)));
writeln;
writeln('OR ', ' True ', ' Maybe', ' False');
writeln('True ', terToStr(terOR(terTrue,terTrue)), ' ', terToStr(terOR(terMayBe,terTrue)), ' ', terToStr(terOR(terFalse,terTrue)));
writeln('Maybe ', terToStr(terOR(terTrue,terMayBe)), ' ', terToStr(terOR(terMayBe,terMayBe)), ' ', terToStr(terOR(terFalse,terMayBe)));
writeln('False ', terToStr(terOR(terTrue,terFalse)), ' ', terToStr(terOR(terMayBe,terFalse)), ' ', terToStr(terOR(terFalse,terFalse)));
writeln;
writeln('IFTHEN', ' True ', ' Maybe', ' False');
writeln('True ', terToStr(terIfThen(terTrue,terTrue)), ' ', terToStr(terIfThen(terMayBe,terTrue)), ' ', terToStr(terIfThen(terFalse,terTrue)));
writeln('Maybe ', terToStr(terIfThen(terTrue,terMayBe)), ' ', terToStr(terIfThen(terMayBe,terMayBe)), ' ', terToStr(terIfThen(terFalse,terMayBe)));
writeln('False ', terToStr(terIfThen(terTrue,terFalse)), ' ', terToStr(terIfThen(terMayBe,terFalse)), ' ', terToStr(terIfThen(terFalse,terFalse)));
writeln;
writeln('EQUAL ', ' True ', ' Maybe', ' False');
writeln('True ', terToStr(terEquals(terTrue,terTrue)), ' ', terToStr(terEquals(terMayBe,terTrue)), ' ', terToStr(terEquals(terFalse,terTrue)));
writeln('Maybe ', terToStr(terEquals(terTrue,terMayBe)), ' ', terToStr(terEquals(terMayBe,terMayBe)), ' ', terToStr(terEquals(terFalse,terMayBe)));
writeln('False ', terToStr(terEquals(terTrue,terFalse)), ' ', terToStr(terEquals(terMayBe,terFalse)), ' ', terToStr(terEquals(terFalse,terFalse)));
writeln;
end.

View file

@ -0,0 +1,81 @@
use v5.36;
package Trit;
use List::Util qw(min max);
our @ISA = qw(Exporter);
our @EXPORT = qw(%E);
my %E = (true => 1, false => -1, maybe => 0);
use overload
'<=>' => sub ($a,$b) { $a->cmp($b) },
'cmp' => sub ($a,$b) { $a->cmp($b) },
'==' => sub ($a,$b,$) { $$a == $$b },
'eq' => sub ($a,$b,$) { $a->equiv($b) },
'>' => sub ($a,$b,$) { $$a > $E{$b} },
'<' => sub ($a,$b,$) { $$a < $E{$b} },
'>=' => sub ($a,$b,$) { $$a >= $$b },
'<=' => sub ($a,$b,$) { $$a <= $$b },
'|' => sub ($a,$b,$,$,$) { $a->or($b) },
'&' => sub ($a,$b,$,$,$) { $a->and($b) },
'!' => sub ($a,$,$) { $a->not() },
'~' => sub ($a,$,$,$,$) { $a->not() },
'neg' => sub ($a,$,$) { -$$a },
'""' => sub ($a,$,$) { $a->tostr() },
'0+' => sub ($a,$,$) { $a->tonum() },
;
sub eqv ($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'
min $$a, $E{$b} # either arg 'false', return 'false', otherwise 'true'
}
# do tests in a manner that avoids overloaded operators
sub new ($class, $v) {
my $value =
! defined $v ? $E{maybe} :
$v =~ /true/ ? $E{true} :
$v =~ /false/ ? $E{false} :
$v =~ /maybe/ ? $E{maybe} :
$v gt $E{maybe} ? $E{true} :
$v lt $E{maybe} ? $E{false} :
$E{maybe} ;
bless \$value, $class;
}
sub tostr ($a) { $$a > $E{maybe} ? 'true' : $$a < $E{maybe} ? 'false' : 'maybe' }
sub tonum ($a) { $$a }
sub not ($a) { Trit->new( -$a ) }
sub cmp ($a,$b) { Trit->new( $a <=> $b ) }
sub and ($a,$b) { Trit->new( min $a, $b ) }
sub or ($a,$b) { Trit->new( max $a, $b ) }
sub equiv ($a,$b) { Trit->new( eqv $a, $b ) }
package main;
Trit->import;
my @a = ( Trit->new($E{true}), Trit->new($E{maybe}), Trit->new($E{false}) );
printf "Codes for logic values: %6s = %d %6s = %d %6s = %d\n", @a[0, 0, 1, 1, 2, 2];
# prefix ! (not) ['~' also can be used]
say "\na\tNOT a";
print "$_\t".(!$_)."\n" for @a;
# infix & (and)
say "\nAND\t" . join("\t",@a);
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)
say "\nEQV\t" . join("\t",@a);
for my $a (@a) { print $a; print "\t" . ($a eq $_) for @a; say '' }
# infix == (equality)
say "\n==\t" . join("\t",@a);
for my $a (@a) { print $a; print "\t" . ($a == $_) for @a; say '' }

View file

@ -0,0 +1,56 @@
(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>
<!--

View file

@ -0,0 +1,58 @@
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.

View file

@ -0,0 +1,3 @@
main =>
println(ternary(10 > 3,'->',maybe).ternary('!')),
println(ternary(4 < 18,'/\\',$not membchk('a',"picat")).ternary('->',maybe).ternary('==',true)).

View file

@ -0,0 +1,25 @@
(de 3not (A)
(or (=0 A) (not A)) )
(de 3and (A B)
(cond
((=T A) B)
((=0 A) (and B 0)) ) )
(de 3or (A B)
(cond
((=T A) T)
((=0 A) (or (=T B) 0))
(T B) ) )
(de 3impl (A B)
(cond
((=T A) B)
((=0 A) (or (=T B) 0))
(T T) ) )
(de 3equiv (A B)
(cond
((=T A) B)
((=0 A) 0)
(T (3not B)) ) )

View file

@ -0,0 +1,7 @@
(for X '(T 0 NIL)
(println 'not X '-> (3not X)) )
(for Fun '((and . 3and) (or . 3or) (implies . 3impl) (equivalent . 3equiv))
(for X '(T 0 NIL)
(for Y '(T 0 NIL)
(println X (car Fun) Y '-> ((cdr Fun) X Y)) ) ) )

View file

@ -0,0 +1,58 @@
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()

View file

@ -0,0 +1,129 @@
class Trit(int):
def __new__(cls, value):
if value == 'TRUE':
value = 1
elif value == 'FALSE':
value = 0
elif value == 'MAYBE':
value = -1
return super(Trit, cls).__new__(cls, value // (abs(value) or 1))
def __repr__(self):
if self > 0:
return 'TRUE'
elif self == 0:
return 'FALSE'
return 'MAYBE'
def __str__(self):
return repr(self)
def __bool__(self):
if self > 0:
return True
elif self == 0:
return False
else:
raise ValueError("invalid literal for bool(): '%s'" % self)
def __or__(self, other):
if isinstance(other, Trit):
return _ttable[(self, other)][1]
else:
try:
return _ttable[(self, Trit(bool(other)))][1]
except:
return NotImplemented
def __ror__(self, other):
if isinstance(other, Trit):
return _ttable[(self, other)][1]
else:
try:
return _ttable[(self, Trit(bool(other)))][1]
except:
return NotImplemented
def __and__(self, other):
if isinstance(other, Trit):
return _ttable[(self, other)][0]
else:
try:
return _ttable[(self, Trit(bool(other)))][0]
except:
return NotImplemented
def __rand__(self, other):
if isinstance(other, Trit):
return _ttable[(self, other)][0]
else:
try:
return _ttable[(self, Trit(bool(other)))][0]
except:
return NotImplemented
def __xor__(self, other):
if isinstance(other, Trit):
return _ttable[(self, other)][2]
else:
try:
return _ttable[(self, Trit(bool(other)))][2]
except:
return NotImplemented
def __rxor__(self, other):
if isinstance(other, Trit):
return _ttable[(self, other)][2]
else:
try:
return _ttable[(self, Trit(bool(other)))][2]
except:
return NotImplemented
def __invert__(self):
return _ttable[self]
def __getattr__(self, name):
if name in ('_n', 'flip'):
# So you can do x._n == x.flip; the inverse of x
# In Python 'not' is strictly boolean so we can't write `not x`
# Same applies to keywords 'and' and 'or'.
return _ttable[self]
else:
raise AttributeError
TRUE, FALSE, MAYBE = Trit(1), Trit(0), Trit(-1)
_ttable = {
# A: -> flip_A
TRUE: FALSE,
FALSE: TRUE,
MAYBE: MAYBE,
# (A, B): -> (A_and_B, A_or_B, A_xor_B)
(MAYBE, MAYBE): (MAYBE, MAYBE, MAYBE),
(MAYBE, FALSE): (FALSE, MAYBE, MAYBE),
(MAYBE, TRUE): (MAYBE, TRUE, MAYBE),
(FALSE, MAYBE): (FALSE, MAYBE, MAYBE),
(FALSE, FALSE): (FALSE, FALSE, FALSE),
(FALSE, TRUE): (FALSE, TRUE, TRUE),
( TRUE, MAYBE): (MAYBE, TRUE, MAYBE),
( TRUE, FALSE): (FALSE, TRUE, TRUE),
( TRUE, TRUE): ( TRUE, TRUE, FALSE),
}
values = ('FALSE', 'TRUE ', 'MAYBE')
print("\nTrit logical inverse, '~'")
for a in values:
expr = '~%s' % a
print(' %s = %s' % (expr, eval(expr)))
for op, ophelp in (('&', 'and'), ('|', 'or'), ('^', 'exclusive-or')):
print("\nTrit logical %s, '%s'" % (ophelp, op))
for a in values:
for b in values:
expr = '%s %s %s' % (a, op, b)
print(' %s = %s' % (expr, eval(expr)))

View file

@ -0,0 +1,105 @@
[ 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

View file

@ -0,0 +1,195 @@
/*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*/

View file

@ -0,0 +1,62 @@
#lang typed/racket
; to avoid the hassle of adding a maybe value that is as special as
; the two standard booleans, we'll use symbols to make our own
(define-type trit (U 'true 'false 'maybe))
(: not (trit -> trit))
(define (not a)
(case a
[(true) 'false]
[(maybe) 'maybe]
[(false) 'true]))
(: and (trit trit -> trit))
(define (and a b)
(case a
[(false) 'false]
[(maybe) (case b
[(false) 'false]
[else 'maybe])]
[(true) (case b
[(true) 'true]
[(maybe) 'maybe]
[(false) 'false])]))
(: or (trit trit -> trit))
(define (or a b)
(case a
[(true) 'true]
[(maybe) (case b
[(true) 'true]
[else 'maybe])]
[(false) (case b
[(true) 'true]
[(maybe) 'maybe]
[(false) 'false])]))
(: ifthen (trit trit -> trit))
(define (ifthen a b)
(case b
[(true) 'true]
[(maybe) (case a
[(false) 'true]
[else 'maybe])]
[(false) (case a
[(true) 'false]
[(maybe) 'maybe]
[(false) 'true])]))
(: iff (trit trit -> trit))
(define (iff a b)
(case a
[(maybe) 'maybe]
[(true) b]
[(false) (not b)]))
(for: : Void ([a (in-list '(true maybe false))])
(printf "~a ~a = ~a~n" (object-name not) a (not a)))
(for: : Void ([proc (in-list (list and or ifthen iff))])
(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))))

View file

@ -0,0 +1,47 @@
# Implementation:
enum Trit <Foo Moo Too>;
sub prefix:<¬> (Trit $a) { Trit(1-($a-1)) }
sub infix:<> (Trit $a, Trit $b) is equiv(&infix:<*>) { $a min $b }
sub infix:<> (Trit $a, Trit $b) is equiv(&infix:<+>) { $a max $b }
sub infix:<> (Trit $a, Trit $b) is equiv(&infix:<..>) { ¬$a max $b }
sub infix:<> (Trit $a, Trit $b) is equiv(&infix:<eq>) { Trit(1 + ($a-1) * ($b-1)) }
# Testing:
say '¬';
say "Too {¬Too}";
say "Moo {¬Moo}";
say "Foo {¬Foo}";
sub tbl (&op,$name) {
say '';
say "$name Too Moo Foo";
say " ";
say "Too{op Too,Too} {op Too,Moo} {op Too,Foo}";
say "Moo{op Moo,Too} {op Moo,Moo} {op Moo,Foo}";
say "Foo{op Foo,Too} {op Foo,Moo} {op Foo,Foo}";
}
tbl(&infix:<>, '');
tbl(&infix:<>, '');
tbl(&infix:<>, '');
tbl(&infix:<>, '');
say '';
say 'Precedence tests should all print "Too":';
say ~(
FooToo Too Too,
Foo(Too Too) Foo,
Too TooFoo Too,
(Too Too)Foo Foo,
¬TooToo Too Too,
¬Too(Too Too) ¬Too,
Too Too ∧ ¬Too Too,
(Too Too) ∧ ¬Too ¬Too,
FooToo FooFoo Too,
FooToo TooFoo Foo,
);

View file

@ -0,0 +1,52 @@
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]
]

View file

@ -0,0 +1,85 @@
# trit.rb - ternary logic
# http://rosettacode.org/wiki/Ternary_logic
require 'singleton'
# MAYBE, the only instance of MaybeClass, enables a system of ternary
# logic using TrueClass#trit, MaybeClass#trit and FalseClass#trit.
#
# !a.trit # ternary not
# a.trit & b # ternary and
# a.trit | b # ternary or
# a.trit ^ b # ternary exclusive or
# a.trit == b # ternary equal
#
# Though +true+ and +false+ are internal Ruby values, +MAYBE+ is not.
# Programs may want to assign +maybe = MAYBE+ in scopes that use
# ternary logic. Then programs can use +true+, +maybe+ and +false+.
class MaybeClass
include Singleton
# maybe.to_s # => "maybe"
def to_s; "maybe"; end
end
MAYBE = MaybeClass.instance
class TrueClass
TritMagic = Object.new
class << TritMagic
def index; 0; end
def !; false; end
def & other; other; end
def | other; true; end
def ^ other; [false, MAYBE, true][other.trit.index]; end
def == other; other; end
end
# Performs ternary logic. See MaybeClass.
# !true.trit # => false
# true.trit & obj # => obj
# true.trit | obj # => true
# true.trit ^ obj # => false, maybe or true
# true.trit == obj # => obj
def trit; TritMagic; end
end
class MaybeClass
TritMagic = Object.new
class << TritMagic
def index; 1; end
def !; MAYBE; end
def & other; [MAYBE, MAYBE, false][other.trit.index]; end
def | other; [true, MAYBE, MAYBE][other.trit.index]; end
def ^ other; MAYBE; end
def == other; MAYBE; end
end
# Performs ternary logic. See MaybeClass.
# !maybe.trit # => maybe
# maybe.trit & obj # => maybe or false
# maybe.trit | obj # => true or maybe
# maybe.trit ^ obj # => maybe
# maybe.trit == obj # => maybe
def trit; TritMagic; end
end
class FalseClass
TritMagic = Object.new
class << TritMagic
def index; 2; end
def !; true; end
def & other; false; end
def | other; other; end
def ^ other; other; end
def == other; [false, MAYBE, true][other.trit.index]; end
end
# Performs ternary logic. See MaybeClass.
# !false.trit # => true
# false.trit & obj # => false
# false.trit | obj # => obj
# false.trit ^ obj # => obj
# false.trit == obj # => false, maybe or true
def trit; TritMagic; end
end

View file

@ -0,0 +1,17 @@
$ irb
irb(main):001:0> require './trit'
=> true
irb(main):002:0> maybe = MAYBE
=> maybe
irb(main):003:0> !true.trit
=> false
irb(main):004:0> !maybe.trit
=> maybe
irb(main):005:0> maybe.trit & false
=> false
irb(main):006:0> maybe.trit | true
=> true
irb(main):007:0> false.trit == true
=> false
irb(main):008:0> false.trit == maybe
=> maybe

View file

@ -0,0 +1,8 @@
require 'trit'
maybe = MAYBE
[true, maybe, false].each do |a|
[true, maybe, false].each do |b|
printf "%5s ^ %5s => %5s\n", a, b, a.trit ^ b
end
end

View file

@ -0,0 +1,58 @@
testFalse = 0 ' F
testDoNotKnow = 1 ' ?
testTrue = 2 ' T
print "Short and long names for ternary logic values"
for i = testFalse to testTrue
print shortName3$(i);" ";longName3$(i)
next i
print
print "Single parameter functions"
print "x";" ";"=x";" ";"not(x)"
for i = testFalse to testTrue
print shortName3$(i);" ";shortName3$(i);" ";shortName3$(not3(i))
next
print
print "Double parameter fuctions"
html "<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>"
for a = testFalse to testTrue
for b = testFalse to testTrue
html "<TR align=center><td>"
html shortName3$(a); "</td><td>";shortName3$(b); "</td><td>"
html shortName3$(and3(a,b));"</td><td>";shortName3$(or3(a,b)); "</td><td>"
html shortName3$(eq3(a,b)); "</td><td>";shortName3$(xor3(a,b));"</td></tr>"
next
next
html "</table>"
function and3(a,b)
and3 = min(a,b)
end function
function or3(a,b)
or3 = max(a,b)
end function
function eq3(a,b)
eq3 = testFalse
if a = tDontKnow or b = tDontKnow then eq3 = tDontKnow
if a = b then eq3 = testTrue
end function
function xor3(a,b)
xor3 = not3(eq3(a,b))
end function
function not3(b)
not3 = 2-b
end function
'------------------------------------------------
function shortName3$(i)
shortName3$ = word$("F ? T", i+1)
end function
function longName3$(i)
longName3$ = word$("False,Don't know,True", i+1, ",")
end function

View file

@ -0,0 +1,107 @@
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!();
}
}

View file

@ -0,0 +1,33 @@
sealed trait Trit { self =>
def nand(that:Trit):Trit=(this,that) match {
case (TFalse, _) => TTrue
case (_, TFalse) => TTrue
case (TMaybe, _) => TMaybe
case (_, TMaybe) => TMaybe
case _ => TFalse
}
def nor(that:Trit):Trit = this.or(that).not()
def and(that:Trit):Trit = this.nand(that).not()
def or(that:Trit):Trit = this.not().nand(that.not())
def not():Trit = this.nand(this)
def imply(that:Trit):Trit = this.nand(that.not())
def equiv(that:Trit):Trit = this.and(that).or(this.nor(that))
}
case object TTrue extends Trit
case object TMaybe extends Trit
case object TFalse extends Trit
object TernaryLogic extends App {
val v=List(TTrue, TMaybe, TFalse)
println("- NOT -")
for(a<-v) println("%6s => %6s".format(a, a.not))
println("\n- AND -")
for(a<-v; b<-v) println("%6s : %6s => %6s".format(a, b, a and b))
println("\n- OR -")
for(a<-v; b<-v) println("%6s : %6s => %6s".format(a, b, a or b))
println("\n- Imply -")
for(a<-v; b<-v) println("%6s : %6s => %6s".format(a, b, a imply b))
println("\n- Equiv -")
for(a<-v; b<-v) println("%6s : %6s => %6s".format(a, b, a equiv b))
}

View file

@ -0,0 +1,114 @@
$ include "seed7_05.s7i";
const type: trit is new enum
False, Maybe, True
end enum;
# Enum types define comparisons (=, <, >, <=, >=, <>) and
# the conversions ord and conv.
const func string: str (in trit: aTrit) is
return [] ("False", "Maybe", "True")[succ(ord(aTrit))];
enable_output(trit); # Allow writing trit values
const array trit: tritNot is [] (True, Maybe, False);
const array array trit: tritAnd is [] (
[] (False, False, False),
[] (False, Maybe, Maybe),
[] (False, Maybe, True ));
const array array trit: tritOr is [] (
[] (False, Maybe, True ),
[] (Maybe, Maybe, True ),
[] (True, True, True ));
const array array trit: tritXor is [] (
[] (False, Maybe, True ),
[] (Maybe, Maybe, Maybe),
[] (True, Maybe, False));
const array array trit: tritImplies is [] (
[] (True, True, True ),
[] (Maybe, Maybe, True ),
[] (False, Maybe, True ));
const array array trit: tritEquiv is [] (
[] (True, Maybe, False),
[] (Maybe, Maybe, Maybe),
[] (False, Maybe, True ));
const func trit: not (in trit: aTrit) is
return tritNot[succ(ord(aTrit))];
const func trit: (in trit: aTrit1) and (in trit: aTrit2) is
return tritAnd[succ(ord(aTrit1))][succ(ord(aTrit2))];
const func trit: (in trit: aTrit1) and (ref func trit: aTrit2) is func
result
var trit: res is False;
begin
if aTrit1 = True then
res := aTrit2;
elsif aTrit1 = Maybe and aTrit2 <> False then
res := Maybe;
end if;
end func;
const func trit: (in trit: aTrit1) or (in trit: aTrit2) is
return tritOr[succ(ord(aTrit1))][succ(ord(aTrit2))];
const func trit: (in trit: aTrit1) or (ref func trit: aTrit2) is func
result
var trit: res is True;
begin
if aTrit1 = False then
res := aTrit2;
elsif aTrit1 = Maybe and aTrit2 <> True then
res := Maybe;
end if;
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))];
const func trit: (in trit: aTrit1) -> (in trit: aTrit2) is
return tritImplies[succ(ord(aTrit1))][succ(ord(aTrit2))];
const func trit: (in trit: aTrit1) == (in trit: aTrit2) is
return tritEquiv[succ(ord(aTrit1))][succ(ord(aTrit2))];
const func trit: rand (in trit: low, in trit: high) is
return trit conv (rand(ord(low), ord(high)));
# Begin of test code
var trit: operand1 is False;
var trit: operand2 is False;
const proc: writeTable (ref func trit: tritExpr, in string: name) is func
begin
writeln;
writeln(" " <& name rpad 7 <& " | False Maybe True");
writeln("---------+---------------------");
for operand1 range False to True do
write(" " <& operand1 rpad 7 <& " | ");
for operand2 range False to True do
write(tritExpr rpad 7);
end for;
writeln;
end for;
end func;
const proc: main is func
begin
writeln(" not" rpad 8 <& " | False Maybe True");
writeln("---------+---------------------");
write(" | ");
for operand1 range False to True do
write(not operand1 rpad 7);
end for;
writeln;
writeTable(operand1 and operand2, "and");
writeTable(operand1 or operand2, "or");
writeTable(operand1 xor operand2, "xor");
writeTable(operand1 -> operand2, "->");
writeTable(operand1 == operand2, "==");
end func;

View file

@ -0,0 +1,86 @@
#!/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;

View file

@ -0,0 +1,67 @@
package require Tcl 8.5
namespace eval ternary {
# Code generator
proc maketable {name count values} {
set sep ""
for {set i 0; set c 97} {$i<$count} {incr i;incr c} {
set v [format "%c" $c]
lappend args $v; append key $sep "$" $v
set sep ","
}
foreach row [split $values \n] {
if {[llength $row]>1} {
lassign $row from to
lappend table $from [list return $to]
}
}
proc $name $args \
[list ckargs $args]\;[concat [list switch -glob --] $key [list $table]]
namespace export $name
}
# Helper command to check argument syntax
proc ckargs argList {
foreach var $argList {
upvar 1 $var v
switch -exact -- $v {
true - maybe - false {
continue
}
default {
return -level 2 -code error "bad ternary value \"$v\""
}
}
}
}
# The "truth" tables; * means anything
maketable not 1 {
true false
maybe maybe
false true
}
maketable and 2 {
true,true true
false,* false
*,false false
* maybe
}
maketable or 2 {
true,* true
*,true true
false,false false
* maybe
}
maketable implies 2 {
false,* true
*,true true
true,false false
* maybe
}
maketable equiv 2 {
*,maybe maybe
maybe,* maybe
true,true true
false,false true
* false
}
}

View file

@ -0,0 +1,10 @@
namespace import ternary::*
puts "x /\\ y == x \\/ y"
puts " x | y || result"
puts "-------+-------++--------"
foreach x {true maybe false} {
foreach y {true maybe false} {
set z [equiv [and $x $y] [or $x $y]]
puts [format " %-5s | %-5s || %-5s" $x $y $z]
}
}

View file

@ -0,0 +1,66 @@
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

View file

@ -0,0 +1,63 @@
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'}
}

View file

@ -0,0 +1,63 @@
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()
}

View file

@ -0,0 +1,68 @@
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