Torvald's Tech Tales

The Verum-Nimply Logic

2023-12-19 03:08 Share This Article

In Terrarum, there is only one logic component called “Signal Blocker”. It has two inputs: Collector and Gate, and whenever the collector receives a signal, it emits the signal, as long as the gate is pulled low; when the gate receives a signal, this component “blocks” it, the component emits nothing regardless of the state of the Collector.

Is it possible to build a logic circuit with this?

As it turns out, we can.

Verum-Nimply Logic

Terrarum allows us to have two atoms required for this logic system.

Verum (⊤)

Verum is merely an “existence of the power”. In other words, it is a signal that is always high.

Nimply (↛)

Nimply is a logic gate modelling of the aforementioned Signal Blocker. Its truth table is as follows:

Collector (left-hand)Gate (right-hand)Emitter
000
010
101
110

And with lots of reasoning, we can build all the logic components out of these:

Falsum (⊥)

Falsum is a signal that is always low, or “absence of the power”. The game also allows the “No-Connect” input, so the construction of this circuit is rarely necessary.

=()

NOT (¬)

Inverter, also known as NOT gate, negates the input.

¬p=(p)

Buffer

Buffer, colloquially known as diode, passes the input as-is.

p=(p) p=¬¬p=((p))

AND (·)

Conjunction, also known as AND gate, outputs a signal when all of its inputs are high.

p·q=(p¬q) =(p(q))

NAND (↑)

NAND gate is an AND gate followed by a NOT gate.

pq=¬(p·q) =¬(p(¬q)) =¬(p(q)) =((p(q)))

OR (+)

Disjunction, also known as OR gate, outputs a signal when one or more of its inputs are high.

p+q=¬(¬p·¬q) =¬((p)·(q)) =¬((p)((q))) =¬((p)q) =(((p)q))

NOR (↓)

NOR gate is an OR gate followed by a NOT gate.

pq=¬(p+q) =¬p·¬q =((p)((q))) =((p)q)

XOR (↮)

XOR output a signal when then number of high inputs is odd.

pq=(p+q)·¬(p·q) =(p+q)·(pq) =(((p)q))·((p(q))) =((((p)q))(((p(q))))) =((((p)q))(p(q)))

Proof-by-Simulation

The logic constructions above can be verified using the following Kotlin code:

val T = true
val F = false
infix fun Boolean.nimply(other: Boolean) = (this && !other)
fun Boolean.toInt() = if (this) 1 else 0
fun printTruthTable(fn: (Boolean, Boolean) -> Boolean) {
    println("p | q | out")
    println("--+---+----")
    for (p0 in 0..1) {
        for (q0 in 0..1) {
            val p = (p0 == 1)
            val q = (q0 == 1)
            println("${p.toInt()} | ${q.toInt()} | ${fn(p, q).toInt()}")
        }
    }
    println()
}
fun printTruthTable2(fn: (Boolean) -> Boolean) {
    println("p | out")
    println("--+----")
    for (p0 in 0..1) {
        val p = (p0 == 1)
        println("${p.toInt()} | ${fn(p).toInt()}")
    }
    println()
}
fun main() {
    println("NIMPLY")
    printTruthTable { p, q -> p nimply q }
    println("FALSUM")
    printTruthTable2 { p -> T nimply T }
    println("NOT")
    printTruthTable2 { p -> T nimply p }
    println("BUFFER")
    printTruthTable2 { p -> T nimply (T nimply p) }
    printTruthTable2 { p -> p nimply F }
    println("AND")
    printTruthTable { p, q -> p nimply (T nimply q) }
    println("NAND")
    printTruthTable { p, q -> T nimply (p nimply (T nimply q)) }
    println("OR")
    printTruthTable { p, q -> T nimply ((T nimply p) nimply q) }
    println("NOR")
    printTruthTable { p, q -> (T nimply p) nimply q }
    println("XOR")
    printTruthTable { p, q -> (T nimply ((T nimply p) nimply q)) nimply (p nimply (T nimply q)) }
}
🖘 Go Back to General