From 6d111e07e2e753a36b9a9d80e3e2f88fde1c2b93 Mon Sep 17 00:00:00 2001 From: goloop Date: Thu, 29 Jun 2023 12:28:30 +0300 Subject: [PATCH] Logical operations errors have been fixed --- README.md | 89 +++++--- trit.go | 480 +++++++++++++++++++++++++++++------------ trit_test.go | 593 ++++++++++++++++++++++++++++++++++----------------- 3 files changed, 804 insertions(+), 358 deletions(-) diff --git a/README.md b/README.md index fdfd417..01c1127 100644 --- a/README.md +++ b/README.md @@ -90,31 +90,70 @@ func main() { The truth table for the three-valued logic system is shown here. It's a mathematical table used in logic—specifically in connection with three-valued algebra, three-valued functions, and propositional calculus—which sets out the functional values of logical expressions on each of their functional arguments, that is, for each combination of values taken by their logical variables. ```shell - NOT AND OR XOR - A | B A | B | C A | B | C A | B | C -------- ----------- ----------- ----------- - T | F T | T | T T | T | T T | T | F - N | N T | N | N T | N | T T | N | T - F | T T | F | F T | F | T T | F | T - N | T | N N | T | T N | T | T - N | N | N N | N | N N | N | F - N | F | F N | F | F N | F | F - F | T | F F | T | T F | T | T - F | N | F F | N | N F | N | T - F | F | F F | F | F F | F | F - - NAND NOR XNOR - A | B | C A | B | C A | B | C ------------ ----------- ----------- - T | T | F T | T | F T | T | T - T | N | T T | N | F T | N | F - T | F | T T | F | F T | F | F - N | T | T N | T | F N | T | F - N | N | T N | N | T N | N | T - N | F | T N | F | F N | F | T - F | T | T F | T | F F | T | F - F | N | T F | N | T F | N | T - F | F | T F | F | T F | F | T + Truth Tables of Three-valued logic + (T=True, N=Nil, F=False) + + NA - Not + MA - Modus Ponens Absorption + LA - Law of Absorption + IA - Implication Absorption + + AND - Logical AND + OR - Logical OR + XOR - Exclusive OR + + NAND - Logical not AND + NOR - Logical not OR + NXOR - Logical not XOR + + IMP - Implication in Lukasevich's Logic + MIN - Minimum + MAX - Maximum + + A | NA A | MA A | LA A | IA + ----+---- ----+---- ----+---- ----+---- + F | T F | F F | F F | F + N | N N | T N | F N | T + T | F T | T T | T T | F + + + A | B | AND A | B | OR A | B | XOR + ---+---+------ ---+---+------ ---+---+------ + F | F | F F | F | F F | F | F + F | N | F F | N | N F | N | N + F | T | F F | T | T F | T | T + N | F | F N | F | N N | F | N + N | N | N N | N | N N | N | N + N | T | N N | T | T N | T | N + T | F | F T | F | T T | F | T + T | N | N T | N | T T | N | N + T | T | T T | T | T T | T | F + + + A | B | NAND A | B | NOR A | B | NXOR + ---+---+------ ---+---+------ ---+---+------ + F | F | T F | F | T F | F | T + F | N | T F | N | N F | N | N + F | T | T F | T | F F | T | F + N | F | T N | F | N N | F | N + N | N | N N | N | N N | N | N + N | T | N N | T | F N | T | N + T | F | T T | F | F T | F | F + T | N | N T | N | F T | N | N + T | T | F T | T | F T | T | T + + + A | B | IMP A | B | MIN A | B | MAX + ---+---+------ ---+---+------ ---+---+------ + F | F | T F | F | F F | F | F + F | N | T F | N | F F | N | N + F | T | T F | T | F F | T | T + N | F | N N | F | F N | F | N + N | N | T N | N | N N | N | N + N | T | T N | T | N N | T | T + T | F | F T | F | F T | F | T + T | N | N T | N | N T | N | T + T | T | T T | T | T T | T | T ``` ## Explanation diff --git a/trit.go b/trit.go index bedcc63..6797143 100644 --- a/trit.go +++ b/trit.go @@ -10,36 +10,74 @@ // science, particularly in scenarios where a "maybe" or "unknown" state // is beneficial, such as database systems and logic circuits. // -// Truth Tables (T=True, N=Nil, F=False) -// -// NOT AND OR XOR -// A | B A | B | C A | B | C A | B | C -// ------- ----------- ----------- ----------- -// T | F T | T | T T | T | T T | T | F -// N | N T | N | N T | N | T T | N | T -// F | T T | F | F T | F | T T | F | T -// N | T | N N | T | T N | T | T -// N | N | N N | N | N N | N | F -// N | F | F N | F | F N | F | F -// F | T | F F | T | T F | T | T -// F | N | F F | N | N F | N | T -// F | F | F F | F | F F | F | F -// -// -// NAND NOR XNOR -// A | B | C A | B | C A | B | C -// ----------- ----------- ----------- -// T | T | F T | T | F T | T | T -// T | N | T T | N | F T | N | F -// T | F | T T | F | F T | F | F -// N | T | T N | T | F N | T | F -// N | N | T N | N | T N | N | T -// N | F | T N | F | F N | F | T -// F | T | T F | T | F F | T | F -// F | N | T F | N | T F | N | T -// F | F | T F | F | T F | F | T +// Truth Tables of Three-valued logic +// (T=True, N=Nil, F=False) +// +// NA - Not +// MA - Modus Ponens Absorption +// LA - Law of Absorption +// IA - Implication Absorption +// +// AND - Logical AND +// OR - Logical OR +// XOR - Exclusive OR +// +// NAND - Logical not AND +// NOR - Logical not OR +// NXOR - Logical not XOR +// +// IMP - Implication in Lukasevich's Logic +// MIN - Minimum +// MAX - Maximum +// +// A | NA A | MA A | LA A | IA +// ----+---- ----+---- ----+---- ----+---- +// F | T F | F F | F F | F +// N | N N | T N | F N | T +// T | F T | T T | T T | F +// +// +// A | B | AND A | B | OR A | B | XOR +// ---+---+------ ---+---+------ ---+---+------ +// F | F | F F | F | F F | F | F +// F | N | F F | N | N F | N | N +// F | T | F F | T | T F | T | T +// N | F | F N | F | N N | F | N +// N | N | N N | N | N N | N | N +// N | T | N N | T | T N | T | N +// T | F | F T | F | T T | F | T +// T | N | N T | N | T T | N | N +// T | T | T T | T | T T | T | F +// +// +// A | B | NAND A | B | NOR A | B | NXOR +// ---+---+------ ---+---+------ ---+---+------ +// F | F | T F | F | T F | F | T +// F | N | T F | N | N F | N | N +// F | T | T F | T | F F | T | F +// N | F | T N | F | N N | F | N +// N | N | N N | N | N N | N | N +// N | T | N N | T | F N | T | N +// T | F | T T | F | F T | F | F +// T | N | N T | N | F T | N | N +// T | T | F T | T | F T | T | T +// +// +// A | B | IMP A | B | MIN A | B | MAX +// ---+---+------ ---+---+------ ---+---+------ +// F | F | T F | F | F F | F | F +// F | N | T F | N | F F | N | N +// F | T | T F | T | F F | T | T +// N | F | N N | F | F N | F | N +// N | N | T N | N | N N | N | N +// N | T | T N | T | N N | T | T +// T | F | F T | F | F T | F | T +// T | N | N T | N | N T | N | T +// T | T | T T | T | T T | T | T package trit +import "reflect" + // Trit represents a trinary digit, which can take on three distinct // states: False, Nil, or True. This type is a fundamental unit of // trinary or ternary logic systems, including trinary computers and @@ -67,6 +105,58 @@ const ( True Trit = 1 ) +// Logic is a special data type from which to determine the state of trit. +type Logic interface { + bool | int | int8 | int16 | int32 | int64 | Trit +} + +// The logicToTrit function converts any logic type to Trit object. +func logicToTrit[T Logic](v T) Trit { + switch any(v).(type) { + case bool: + if any(v).(bool) { + return True + } + return False + case int, int8, int16, int32, int64: + switch reflect.TypeOf(v).Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, + reflect.Int32, reflect.Int64: + intValue := reflect.ValueOf(v).Int() + if intValue > 0 { + return True + } else if intValue < 0 { + return False + } + + return Nil + } + case Trit: + return any(v).(Trit) + } + + return Nil +} + +// Default sets the default value for the trit-object +// if this one has a Nil state. +// +// Example usage: +// +// t := trit.Nil +// trit.Default(&t, trit.True) +// fmt.Println(t.String()) // Output: True +func Default[T Logic](t *Trit, v T) Trit { + // If the trit is not Nil, return the trit. + if t.Val() != Nil { + return *t + } + + trit := logicToTrit(v) + *t = trit + return *t +} + // Def is a method that checks if the value of the Trit is Nil. // If it is, it sets the Trit to the given Trit argument. // @@ -83,35 +173,37 @@ func (t *Trit) Def(trit Trit) Trit { return *t } -// DefTrue is a method that checks if the value of the Trit is Nil. +// TrueIfNil is a method that checks if the value of the Trit is Nil. // If it is, it sets the Trit to True. // It then returns the updated Trit. // // Example usage: // // t := trit.Nil -// t.DefTrue() +// t.TrueIfNil() // fmt.Println(t.String()) // Output: True -func (t *Trit) DefTrue() Trit { +func (t *Trit) TrueIfNil() Trit { if t.Val() == Nil { *t = True } + return *t } -// DefFalse is a method that checks if the value of the Trit is Nil. +// FalseIfNil is a method that checks if the value of the Trit is Nil. // If it is, it sets the Trit to False. // It then returns the updated Trit. // // Example usage: // // t := trit.Nil -// t.DefFalse() +// t.FalseIfNil() // fmt.Println(t.String()) // Output: False -func (t *Trit) DefFalse() Trit { +func (t *Trit) FalseIfNil() Trit { if t.Val() == Nil { *t = False } + return *t } @@ -128,6 +220,7 @@ func (t *Trit) Clean() Trit { if t.Val() == Nil { *t = Nil } + return *t } @@ -139,9 +232,10 @@ func (t *Trit) Clean() Trit { // t := trit.Trit(-2) // fmt.Println(t.IsFalse()) // Output: true func (t Trit) IsFalse() bool { - if t < 0 { + if int8(t) < 0 { return true } + return false } @@ -153,9 +247,10 @@ func (t Trit) IsFalse() bool { // t := trit.Trit(0) // fmt.Println(t.IsNil()) // Output: true func (t Trit) IsNil() bool { - if t == 0 { + if int8(t) == 0 { return true } + return false } @@ -167,9 +262,10 @@ func (t Trit) IsNil() bool { // t := trit.Trit(2) // fmt.Println(t.IsTrue()) // Output: true func (t Trit) IsTrue() bool { - if t > 0 { + if int8(t) > 0 { return true } + return false } @@ -204,11 +300,11 @@ func (t *Trit) Set(v int) Trit { // t := trit.Trit(7) // fmt.Println(t.Val().String()) // Output: True func (t Trit) Val() Trit { - if t < 0 { + if t.IsFalse() { return False } - if t > 0 { + if t.IsTrue() { return True } @@ -222,7 +318,7 @@ func (t Trit) Val() Trit { // // t := trit.Trit(7) // t.Norm() -// fmt.Println(t.String()) // Output: True +// fmt.Println(t.Int()) // Output: 1 func (t *Trit) Norm() Trit { *t = t.Val() return *t @@ -259,9 +355,9 @@ func (t Trit) String() string { // Not performs a logical NOT operation on a Trit value and returns the result. // This function applies the following rules based on the truth table for NOT: -// - Not(True) => False -// - Not(Nil) => Nil // - Not(False) => True +// - Not(Nil) => Nil +// - Not(True) => False // // Example usage: // @@ -279,24 +375,84 @@ func (t Trit) Not() Trit { return Nil } +// Ma performs a logical MA (Modus Ponens Absorption) operation on a Trit +// value and returns the result. This function applies the following rules +// based on the truth table for MA: +// - Ma(False) => False +// - Ma(Nil) => True +// - Ma(True) => True +// +// Example usage: +// +// a := trit.True +// result := a.Ma() +// fmt.Println(result.String()) // Output: True +func (t Trit) Ma() Trit { + if t.Val() == False { + return False + } + + return True +} + +// La performs a logical LA (Law of Absorption) operation on a Trit value +// and returns the result. This function applies the following rules based +// on the truth table for LA: +// - La(False) => False +// - La(Nil) => False +// - La(True) => True +// +// Example usage: +// +// a := trit.True +// result := a.La() +// fmt.Println(result.String()) // Output: True +func (t Trit) La() Trit { + if t.Val() == True { + return True + } + + return False +} + +// Ia performs a logical IA (Implication Absorption) operation on a Trit +// values and returns the result. This function applies the following +// rules based on the truth table for IA: +// - Ia(False) => False +// - Ia(Nil) => True +// - Ia(True) => False +// +// Example usage: +// +// a := trit.True +// result := a.Ia() +// fmt.Println(result.String()) // Output: False +func (t Trit) Ia() Trit { + if t.Val() == Nil { + return True + } + + return False +} + // And performs a logical AND operation between two Trit values and returns // the result. This function applies the following rules based on the truth // table for AND: -// - And(True, True) => True -// - And(True, Nil) => Nil -// - And(True, False) => False -// - And(Nil, True) => Nil -// - And(Nil, Nil) => Nil -// - And(Nil, False) => False -// - And(False, True) => False -// - And(False, Nil) => False // - And(False, False) => False +// - And(False, Nil) => False +// - And(False, True) => False +// - And(Nil, False) => False +// - And(Nil, Nil) => Nil +// - And(Nil, True) => Nil +// - And(True, False) => False +// - And(True, Nil) => Nil +// - And(True, True) => True // // Example usage: // -// t1 := trit.True -// t2 := trit.Nil -// result := t1.And(t2) +// a := trit.True +// b := trit.Nil +// result := a.And(b) // fmt.Println(result.String()) // Output: Nil func (t Trit) And(trit Trit) Trit { if t.Val() == False || trit.Val() == False { @@ -313,21 +469,21 @@ func (t Trit) And(trit Trit) Trit { // Or performs a logical OR operation between two Trit values and returns // the result. This function applies the following rules based on the truth // table for OR: -// - Or(True, True) => True -// - Or(True, Nil) => True -// - Or(True, False) => True -// - Or(Nil, True) => True -// - Or(Nil, Nil) => Nil -// - Or(Nil, False) => Nil -// - Or(False, True) => True -// - Or(False, Nil) => Nil // - Or(False, False) => False +// - Or(False, Nil) => Nil +// - Or(False, True) => True +// - Or(Nil, False) => Nil +// - Or(Nil, Nil) => Nil +// - Or(Nil, True) => True +// - Or(True, False) => True +// - Or(True, Nil) => True +// - Or(True, True) => True // // Example usage: // -// t1 := trit.True -// t2 := trit.False -// result := t1.Or(t2) +// a := trit.True +// b := trit.False +// result := a.Or(b) // fmt.Println(result.String()) // Output: True func (t Trit) Or(trit Trit) Trit { if t.Val() == True || trit.Val() == True { @@ -344,116 +500,174 @@ func (t Trit) Or(trit Trit) Trit { // Xor performs a logical XOR operation between two Trit values and returns // the result. This function applies the following rules based on the truth // table for XOR: -// - Xor(True, True) => False -// - Xor(True, Nil) => Nil -// - Xor(True, False) => True -// - Xor(Nil, True) => Nil -// - Xor(Nil, Nil) => False -// - Xor(Nil, False) => Nil -// - Xor(False, True) => True -// - Xor(False, Nil) => Nil // - Xor(False, False) => False +// - Xor(False, Nil) => Nil +// - Xor(False, True) => True +// - Xor(Nil, False) => Nil +// - Xor(Nil, Nil) => Nil +// - Xor(Nil, True) => Nil +// - Xor(True, False) => True +// - Xor(True, Nil) => Nil +// - Xor(True, True) => False // // Example usage: // -// t1 := trit.True -// t2 := trit.False -// result := t1.Xor(t2) +// a := trit.True +// b := trit.False +// result := a.Xor(b) // fmt.Println(result.String()) // Output: True func (t Trit) Xor(trit Trit) Trit { - if t.Val() == trit.Val() { - return False - } - + // Check first, because Xor(Nil, Nil) should be Nil. if t.Val() == Nil || trit.Val() == Nil { return Nil } + // Pay attention, Nil == Nil != False + if t.Val() == trit.Val() { + return False + } + return True } // Nand performs a logical NAND operation between two Trit values and returns // the result. This function applies the following rules based on the truth // table for NAND: -// - Nand(True, True) => False -// - Nand(True, Nil) => True -// - Nand(True, False) => True -// - Nand(Nil, True) => True -// - Nand(Nil, Nil) => True -// - Nand(Nil, False) => True -// - Nand(False, True) => True -// - Nand(False, Nil) => True // - Nand(False, False) => True +// - Nand(False, Nil) => True +// - Nand(False, True) => True +// - Nand(Nil, False) => True +// - Nand(Nil, Nil) => Nil +// - Nand(Nil, True) => Nil +// - Nand(True, False) => True +// - Nand(True, Nil) => Nil +// - Nand(True, True) => False // // Example usage: // -// t1 := trit.True -// t2 := trit.Nil -// result := t1.Nand(t2) +// a := trit.True +// b := trit.Nil +// result := a.Nand(b) // fmt.Println(result.String()) // Output: True func (t Trit) Nand(trit Trit) Trit { - if t.Val() == False || trit.Val() == False { - return True - } - if t.Val() == True && trit.Val() == True { - return False - } - - return True + return t.And(trit).Not() } // Nor performs a logical NOR operation between two Trit values and returns // the result. This function applies the following rules based on the truth // table for NOR: -// - Nor(True, True) => False -// - Nor(True, Nil) => False -// - Nor(True, False) => False -// - Nor(Nil, True) => False -// - Nor(Nil, Nil) => True -// - Nor(Nil, False) => True -// - Nor(False, True) => False -// - Nor(False, Nil) => True // - Nor(False, False) => True +// - Nor(False, Nil) => Nil +// - Nor(False, True) => False +// - Nor(Nil, False) => Nil +// - Nor(Nil, Nil) => Nil +// - Nor(Nil, True) => False +// - Nor(True, False) => False +// - Nor(True, Nil) => False +// - Nor(True, True) => False // // Example usage: // -// t1 := trit.True -// t2 := trit.False -// result := t1.Nor(t2) +// a := trit.True +// b := trit.False +// result := a.Nor(b) // fmt.Println(result.String()) // Output: False func (t Trit) Nor(trit Trit) Trit { - // t.Or(trit).Not() - if t.Val() == True || trit.Val() == True { - return False - } else if t.Val() == Nil || trit.Val() == Nil { - return Nil - } - - return True + return t.Or(trit).Not() } -// Xnor performs a logical XNOR operation between two Trit values and returns +// Nxor performs a logical XNOR operation between two Trit values and returns // the result. This function applies the following rules based on the truth // table for XNOR: -// - Xnor(True, True) => True -// - Xnor(True, Nil) => Nil -// - Xnor(True, False) => False -// - Xnor(Nil, True) => Nil -// - Xnor(Nil, Nil) => True -// - Xnor(Nil, False) => Nil -// - Xnor(False, True) => False -// - Xnor(False, Nil) => Nil -// - Xnor(False, False) => True +// - Nxor(False, False) => True +// - Nxor(False, Nil) => Nil +// - Nxor(False, True) => False +// - Nxor(Nil, False) => Nil +// - Nxor(Nil, Nil) => Nil +// - Nxor(Nil, True) => Nil +// - Nxor(True, False) => False +// - Nxor(True, Nil) => Nil +// - Nxor(True, True) => True // // Example usage: // -// t1 := trit.True -// t2 := trit.False -// result := t1.Xnor(t2) +// a := trit.True +// b := trit.False +// result := a.Nxor(b) // fmt.Println(result.String()) // Output: False -func (t Trit) Xnor(trit Trit) Trit { - // t.Xor(trit).Not() - if t.Val() == trit.Val() { +func (t Trit) Nxor(trit Trit) Trit { + return t.Xor(trit).Not() +} + +// Min performs a logical MIN operation between two Trit values and returns +// the result. This function applies the following rules based on the truth +// table for MIN: +// - Min(False, False) => False +// - Min(False, Nil) => False +// - Min(False, True) => False +// - Min(Nil, False) => False +// - Min(Nil, Nil) => Nil +// - Min(Nil, True) => Nil +// - Min(True, False) => False +// - Min(True, Nil) => Nil +// - Min(True, True) => True +// +// Example usage: +// +// a := trit.True +// b := trit.False +// result := a.Min(b) +// fmt.Println(result.String()) // Output: False +func (t Trit) Min(trit Trit) Trit { + return t.And(trit) +} + +// Max performs a logical MAX operation between two Trit values and returns +// the result. This function applies the following rules based on the truth +// table for MAX: +// - Max(False, False) => False +// - Max(False, Nil) => Nil +// - Max(False, True) => True +// - Max(Nil, False) => Nil +// - Max(Nil, Nil) => Nil +// - Max(Nil, True) => True +// - Max(True, False) => True +// - Max(True, Nil) => True +// - Max(True, True) => True +// +// Example usage: +// +// a := trit.True +// b := trit.False +// result := a.Max(b) +// fmt.Println(result.String()) // Output: True +func (t Trit) Max(trit Trit) Trit { + return t.Or(trit) +} + +// Imp performs a logical IMP operation between two Trit values and returns +// the result. This function applies the following rules based on the truth +// table for IMP: +// - Imp(False, False) => True +// - Imp(False, Nil) => True +// - Imp(False, True) => True +// - Imp(Nil, False) => Nil +// - Imp(Nil, Nil) => True +// - Imp(Nil, True) => True +// - Imp(True, False) => False +// - Imp(True, Nil) => Nil +// - Imp(True, True) => True +// +// Example usage: +// +// a := trit.True +// b := trit.False +// result := a.Imp(b) +// fmt.Println(result.String()) // Output: False +func (t Trit) Imp(trit Trit) Trit { + if t.Val() == Nil && trit.Val() == Nil { + return True + } else if t.Val() == False || trit.Val() == True { return True } else if t.Val() == Nil || trit.Val() == Nil { return Nil diff --git a/trit_test.go b/trit_test.go index 1118a02..3e2bbee 100644 --- a/trit_test.go +++ b/trit_test.go @@ -2,6 +2,59 @@ package trit import "testing" +// TestDefault tests the Default method. +func TestDefault(t *testing.T) { + t.Run("Default with bool value", func(t *testing.T) { + t1 := Nil + Default(&t1, true) + if t1 != True { + t.Errorf("Default did not update Nil to True") + } + + t2 := Nil + Default(&t2, false) + if t2 != False { + t.Errorf("Default did not update Nil to False") + } + }) + + t.Run("Default with numeric value", func(t *testing.T) { + t1 := Nil + Default(&t1, int32(1)) // for example int32 + if t1 != True { + t.Errorf("Default did not update Nil to True") + } + + t2 := Nil + Default(&t2, int64(-1)) // for example int64 + if t2 != False { + t.Errorf("Default did not update Nil to False") + } + }) + + t.Run("Default with Trit value", func(t *testing.T) { + t1 := Nil + Default(&t1, True) + if t1 != True { + t.Errorf("Default did not update Nil to True") + } + + t2 := Nil + Default(&t2, False) + if t2 != False { + t.Errorf("Default did not update Nil to False") + } + }) + + t.Run("Should not update non-Nil Trit", func(t *testing.T) { + t1 := True + Default(&t1, false) + if t1 != True { + t.Errorf("Default updated non-Nil Trit") + } + }) +} + // TestDef tests the Def method. func TestDef(t *testing.T) { t.Run("Def should update Nil to True", func(t *testing.T) { @@ -29,56 +82,56 @@ func TestDef(t *testing.T) { }) } -// TestDefTrue tests the DefTrue method. -func TestDefTrue(t *testing.T) { - t.Run("DefTrue should set Nil to True", func(t *testing.T) { +// TestTrueIfNil tests the TrueIfNil method. +func TestTrueIfNil(t *testing.T) { + t.Run("Should set Nil to True", func(t *testing.T) { tr := Nil - tr.DefTrue() + tr.TrueIfNil() if tr != True { - t.Errorf("DefTrue did not set Nil to True") + t.Errorf("TrueIfNil did not set Nil to True") } }) - t.Run("DefTrue should not change True to False", func(t *testing.T) { + t.Run("Should not change True to False", func(t *testing.T) { tr := True - tr.DefTrue() + tr.TrueIfNil() if tr != True { - t.Errorf("DefTrue changed True to False") + t.Errorf("TrueIfNil changed True to False") } }) - t.Run("DefTrue should not change False to True", func(t *testing.T) { + t.Run("Should not change False to True", func(t *testing.T) { tr := False - tr.DefTrue() + tr.TrueIfNil() if tr != False { - t.Errorf("DefTrue changed False to True") + t.Errorf("TrueIfNil changed False to True") } }) } -// TestDefFalse tests the DefFalse method. -func TestDefFalse(t *testing.T) { - t.Run("DefFalse should set Nil to False", func(t *testing.T) { +// TestFalseIfNil tests the FalseIfNil method. +func TestFalseIfNil(t *testing.T) { + t.Run("Should set Nil to False", func(t *testing.T) { tr := Nil - tr.DefFalse() + tr.FalseIfNil() if tr != False { - t.Errorf("DefFalse did not set Nil to False") + t.Errorf("FalseIfNil did not set Nil to False") } }) - t.Run("DefFalse should not change False to True", func(t *testing.T) { + t.Run("Should not change False to True", func(t *testing.T) { tr := False - tr.DefFalse() + tr.FalseIfNil() if tr != False { - t.Errorf("DefFalse changed False to True") + t.Errorf("FalseIfNil changed False to True") } }) - t.Run("DefFalse should not change True to False", func(t *testing.T) { + t.Run("Should not change True to False", func(t *testing.T) { tr := True - tr.DefFalse() + tr.FalseIfNil() if tr != True { - t.Errorf("DefFalse changed True to False") + t.Errorf("FalseIfNil changed True to False") } }) } @@ -310,209 +363,349 @@ func TestString(t *testing.T) { // TestNot tests the Not method. func TestNot(t *testing.T) { - t.Run("Not should return False for True", func(t *testing.T) { - tr := True - result := tr.Not() - if result != False { - t.Errorf("Not did not return False for True") - } - }) + tests := []struct { + name string + in Trit + out Trit + }{ + {"Not should return True for False", False, True}, + {"Not should return Nil for Nil", Nil, Nil}, + {"Not should return False for True", True, False}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := test.in.Not() + if result != test.out { + t.Errorf("Not did not return %v for %v", test.out, test.in) + } + }) + } +} - t.Run("Not should return Nil for Nil", func(t *testing.T) { - tr := Nil - result := tr.Not() - if result != Nil { - t.Errorf("Not did not return Nil for Nil") - } - }) +// TestMa tests the Ma method. +func TestMa(t *testing.T) { + tests := []struct { + name string + in Trit + out Trit + }{ + {"Ma should return False for False", False, False}, + {"Ma should return True for Nil", Nil, True}, + {"Ma should return True for True", True, True}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := test.in.Ma() + if result != test.out { + t.Errorf("Ma did not return %v for %v", test.out, test.in) + } + }) + } +} - t.Run("Not should return True for False", func(t *testing.T) { - tr := False - result := tr.Not() - if result != True { - t.Errorf("Not did not return True for False") - } - }) +// TestLa tests the La method. +func TestLa(t *testing.T) { + tests := []struct { + name string + in Trit + out Trit + }{ + {"La should return False for False", False, False}, + {"La should return False for Nil", Nil, False}, + {"La should return True for True", True, True}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := test.in.La() + if result != test.out { + t.Errorf("La did not return %v for %v", test.out, test.in) + } + }) + } +} + +// TestIa tests the Ia method. +func TestIa(t *testing.T) { + tests := []struct { + name string + in Trit + out Trit + }{ + {"Ia should return False for False", False, False}, + {"Ia should return True for Nil", Nil, True}, + {"Ia should return False for True", True, False}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := test.in.Ia() + if result != test.out { + t.Errorf("Ia did not return %v for %v", test.out, test.in) + } + }) + } } // TestAnd tests the And method. func TestAnd(t *testing.T) { - t.Run("And should return True for (True, True)", func(t *testing.T) { - t1 := True - t2 := True - result := t1.And(t2) - if result != True { - t.Errorf("And did not return True for (True, True)") - } - }) - - t.Run("And should return Nil for (True, Nil)", func(t *testing.T) { - t1 := True - t2 := Nil - result := t1.And(t2) - if result != Nil { - t.Errorf("And did not return Nil for (True, Nil)") - } - }) - - t.Run("And should return False for (True, False)", func(t *testing.T) { - t1 := True - t2 := False - result := t1.And(t2) - if result != False { - t.Errorf("And did not return False for (True, False)") - } - }) + tests := []struct { + name string + a Trit + b Trit + out Trit + }{ + {"And should return False for (False, False)", False, False, False}, + {"And should return False for (False, Nil)", False, Nil, False}, + {"And should return False for (False, True)", False, True, False}, + {"And should return False for (Nil, False)", Nil, False, False}, + {"And should return Nil for (Nil, Nil)", Nil, Nil, Nil}, + {"And should return Nil for (Nil, True)", Nil, True, Nil}, + {"And should return False for (True, False)", True, False, False}, + {"And should return Nil for (True, Nil)", True, Nil, Nil}, + {"And should return True for (True, True)", True, True, True}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := test.a.And(test.b) + if result != test.out { + t.Errorf("And did not return %v for (%v, %v)", test.out, test.a, test.b) + } + }) + } } // TestOr tests the Or method. func TestOr(t *testing.T) { - t.Run("Or should return True for (True, True)", func(t *testing.T) { - t1 := True - t2 := True - result := t1.Or(t2) - if result != True { - t.Errorf("Or did not return True for (True, True)") - } - }) - - t.Run("Or should return True for (True, Nil)", func(t *testing.T) { - t1 := True - t2 := Nil - result := t1.Or(t2) - if result != True { - t.Errorf("Or did not return True for (True, Nil)") - } - }) - - t.Run("Or should return True for (True, False)", func(t *testing.T) { - t1 := True - t2 := False - result := t1.Or(t2) - if result != True { - t.Errorf("Or did not return True for (True, False)") - } - }) + tests := []struct { + name string + a Trit + b Trit + out Trit + }{ + {"Or should return False for (False, False)", False, False, False}, + {"Or should return Nil for (False, Nil)", False, Nil, Nil}, + {"Or should return True for (False, True)", False, True, True}, + {"Or should return Nil for (Nil, False)", Nil, False, Nil}, + {"Or should return Nil for (Nil, Nil)", Nil, Nil, Nil}, + {"Or should return True for (Nil, True)", Nil, True, True}, + {"Or should return True for (True, False)", True, False, True}, + {"Or should return True for (True, Nil)", True, Nil, True}, + {"Or should return True for (True, True)", True, True, True}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := test.a.Or(test.b) + if result != test.out { + t.Errorf("Or did not return %v for (%v, %v)", test.out, test.a, test.b) + } + }) + } } // TestXor tests the Xor method. func TestXor(t *testing.T) { - t.Run("Xor should return False for (True, True)", func(t *testing.T) { - t1 := True - t2 := True - result := t1.Xor(t2) - if result != False { - t.Errorf("Xor did not return False for (True, True)") - } - }) - - t.Run("Xor should return Nil for (True, Nil)", func(t *testing.T) { - t1 := True - t2 := Nil - result := t1.Xor(t2) - if result != Nil { - t.Errorf("Xor did not return Nil for (True, Nil)") - } - }) - - t.Run("Xor should return True for (True, False)", func(t *testing.T) { - t1 := True - t2 := False - result := t1.Xor(t2) - if result != True { - t.Errorf("Xor did not return True for (True, False)") - } - }) - - // Add more test cases to cover all possible scenarios + tests := []struct { + name string + a Trit + b Trit + out Trit + }{ + {"Xor should return False for (False, False)", False, False, False}, + {"Xor should return Nil for (False, Nil)", False, Nil, Nil}, + {"Xor should return True for (False, True)", False, True, True}, + {"Xor should return Nil for (Nil, False)", Nil, False, Nil}, + {"Xor should return Nil for (Nil, Nil)", Nil, Nil, Nil}, + {"Xor should return Nil for (Nil, True)", Nil, True, Nil}, + {"Xor should return True for (True, False)", True, False, True}, + {"Xor should return Nil for (True, Nil)", True, Nil, Nil}, + {"Xor should return False for (True, True)", True, True, False}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := test.a.Xor(test.b) + if result != test.out { + t.Errorf("Xor did not return %v for (%v, %v)", test.out, test.a, test.b) + } + }) + } } // TestNand tests the Nand method. func TestNand(t *testing.T) { - t.Run("Nand should return False for (True, True)", func(t *testing.T) { - t1 := True - t2 := True - result := t1.Nand(t2) - if result != False { - t.Errorf("Nand did not return False for (True, True)") - } - }) - - t.Run("Nand should return True for (True, Nil)", func(t *testing.T) { - t1 := True - t2 := Nil - result := t1.Nand(t2) - if result != True { - t.Errorf("Nand did not return True for (True, Nil)") - } - }) - - t.Run("Nand should return True for (True, False)", func(t *testing.T) { - t1 := True - t2 := False - result := t1.Nand(t2) - if result != True { - t.Errorf("Nand did not return True for (True, False)") - } - }) + tests := []struct { + name string + a Trit + b Trit + out Trit + }{ + {"Nand should return True for (False, False)", False, False, True}, + {"Nand should return True for (False, Nil)", False, Nil, True}, + {"Nand should return True for (False, True)", False, True, True}, + {"Nand should return True for (Nil, False)", Nil, False, True}, + {"Nand should return Nil for (Nil, Nil)", Nil, Nil, Nil}, + {"Nand should return Nil for (Nil, True)", Nil, True, Nil}, + {"Nand should return True for (True, False)", True, False, True}, + {"Nand should return Nil for (True, Nil)", True, Nil, Nil}, + {"Nand should return False for (True, True)", True, True, False}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := test.a.Nand(test.b) + if result != test.out { + t.Errorf("Nand did not return %v for (%v, %v)", test.out, test.a, test.b) + } + }) + } } // TestNor tests the Nor method. func TestNor(t *testing.T) { - t.Run("Nor should return False for (True, True)", func(t *testing.T) { - t1 := True - t2 := True - result := t1.Nor(t2) - if result != False { - t.Errorf("Nor did not return False for (True, True)") - } - }) - - t.Run("Nor should return False for (True, Nil)", func(t *testing.T) { - t1 := True - t2 := Nil - result := t1.Nor(t2) - if result != False { - t.Errorf("Nor did not return False for (True, Nil)") - } - }) + tests := []struct { + name string + a Trit + b Trit + out Trit + }{ + {"Nor should return True for (False, False)", False, False, True}, + {"Nor should return Nil for (False, Nil)", False, Nil, Nil}, + {"Nor should return False for (False, True)", False, True, False}, + {"Nor should return Nil for (Nil, False)", Nil, False, Nil}, + {"Nor should return Nil for (Nil, Nil)", Nil, Nil, Nil}, + {"Nor should return False for (Nil, True)", Nil, True, False}, + {"Nor should return False for (True, False)", True, False, False}, + {"Nor should return False for (True, Nil)", True, Nil, False}, + {"Nor should return False for (True, True)", True, True, False}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := test.a.Nor(test.b) + if result != test.out { + t.Errorf("Nor did not return %v for (%v, %v)", test.out, test.a, test.b) + } + }) + } +} - t.Run("Nor should return False for (True, False)", func(t *testing.T) { - t1 := True - t2 := False - result := t1.Nor(t2) - if result != False { - t.Errorf("Nor did not return False for (True, False)") - } - }) +// TestNxor tests the Nxor method. +func TestNxor(t *testing.T) { + tests := []struct { + name string + a Trit + b Trit + out Trit + }{ + {"Nxor should return True for (False, False)", False, False, True}, + {"Nxor should return Nil for (False, Nil)", False, Nil, Nil}, + {"Nxor should return False for (False, True)", False, True, False}, + {"Nxor should return Nil for (Nil, False)", Nil, False, Nil}, + {"Nxor should return Nil for (Nil, Nil)", Nil, Nil, Nil}, + {"Nxor should return Nil for (Nil, True)", Nil, True, Nil}, + {"Nxor should return False for (True, False)", True, False, False}, + {"Nxor should return Nil for (True, Nil)", True, Nil, Nil}, + {"Nxor should return True for (True, True)", True, True, True}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := test.a.Nxor(test.b) + if result != test.out { + t.Errorf("Nxor did not return %v for (%v, %v)", test.out, test.a, test.b) + } + }) + } } -// TestXnor tests the Xnor method. -func TestXnor(t *testing.T) { - t.Run("Xnor should return True for (True, True)", func(t *testing.T) { - t1 := True - t2 := True - result := t1.Xnor(t2) - if result != True { - t.Errorf("Xnor did not return True for (True, True)") - } - }) +// TestMin tests the Min method. +func TestMin(t *testing.T) { + tests := []struct { + name string + a Trit + b Trit + out Trit + }{ + {"Min should return False for (False, False)", False, False, False}, + {"Min should return False for (False, Nil)", False, Nil, False}, + {"Min should return False for (False, True)", False, True, False}, + {"Min should return False for (Nil, False)", Nil, False, False}, + {"Min should return Nil for (Nil, Nil)", Nil, Nil, Nil}, + {"Min should return Nil for (Nil, True)", Nil, True, Nil}, + {"Min should return False for (True, False)", True, False, False}, + {"Min should return Nil for (True, Nil)", True, Nil, Nil}, + {"Min should return True for (True, True)", True, True, True}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := test.a.Min(test.b) + if result != test.out { + t.Errorf("Min did not return %v for (%v, %v)", test.out, test.a, test.b) + } + }) + } +} - t.Run("Xnor should return Nil for (True, Nil)", func(t *testing.T) { - t1 := True - t2 := Nil - result := t1.Xnor(t2) - if result != Nil { - t.Errorf("Xnor did not return Nil for (True, Nil)") - } - }) +// TestMax tests the Max method. +func TestMax(t *testing.T) { + tests := []struct { + name string + a Trit + b Trit + out Trit + }{ + {"Max should return False for (False, False)", False, False, False}, + {"Max should return Nil for (False, Nil)", False, Nil, Nil}, + {"Max should return True for (False, True)", False, True, True}, + {"Max should return Nil for (Nil, False)", Nil, False, Nil}, + {"Max should return Nil for (Nil, Nil)", Nil, Nil, Nil}, + {"Max should return True for (Nil, True)", Nil, True, True}, + {"Max should return True for (True, False)", True, False, True}, + {"Max should return True for (True, Nil)", True, Nil, True}, + {"Max should return True for (True, True)", True, True, True}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := test.a.Max(test.b) + if result != test.out { + t.Errorf("Max did not return %v for (%v, %v)", test.out, test.a, test.b) + } + }) + } +} - t.Run("Xnor should return False for (True, False)", func(t *testing.T) { - t1 := True - t2 := False - result := t1.Xnor(t2) - if result != False { - t.Errorf("Xnor did not return False for (True, False)") - } - }) +// TestImp tests the Imp method. +func TestImp(t *testing.T) { + tests := []struct { + name string + a Trit + b Trit + out Trit + }{ + {"Imp should return True for (False, False)", False, False, True}, + {"Imp should return True for (False, Nil)", False, Nil, True}, + {"Imp should return True for (False, True)", False, True, True}, + {"Imp should return Nil for (Nil, False)", Nil, False, Nil}, + {"Imp should return True for (Nil, Nil)", Nil, Nil, True}, + {"Imp should return True for (Nil, True)", Nil, True, True}, + {"Imp should return False for (True, False)", True, False, False}, + {"Imp should return Nil for (True, Nil)", True, Nil, Nil}, + {"Imp should return True for (True, True)", True, True, True}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := test.a.Imp(test.b) + if result != test.out { + t.Errorf("Imp did not return %v for (%v, %v)", test.out, test.a, test.b) + } + }) + } }