August 26, 2024
P46 - Truth tables for logical expressions.
Define functions and_, or_, nand_, nor_, xor_, impl_, and equ_ (for logical equivalence) which return true or false according to the result of their respective operations.
> true.and_(true)
true
> true.xor_(true)
false
Write a function called printTruthTable which prints the truth table of a given logical expression.
> printTruthTable{ a, b -> a.and_(a.or_(b.not_())) }
a b result
true true true
true false true
false true false
false false false
kotlin
@file:Suppress("NOTHING_TO_INLINE", "unused", "BooleanLiteralArgument")
package org.kotlin99.logic
import com.natpryce.hamkrest.assertion.assertThat
import com.natpryce.hamkrest.equalTo
import org.junit.Test
inline fun Boolean.not_() = !this
inline fun Boolean.and_(other: Boolean) = this && other
inline fun Boolean.or_(other: Boolean) = this || other
inline fun Boolean.nand_(other: Boolean) = this.and_(other).not_()
inline fun Boolean.nor_(other: Boolean) = this.or_(other).not_()
inline fun Boolean.xor_(other: Boolean) = this.xor(other)
inline fun Boolean.equ_(other: Boolean) = this.xor_(other).not_()
inline fun Boolean.impl_(other: Boolean) = this.or_(other.not_())
fun truthTable(f: (Boolean, Boolean) -> Boolean): List<Row> =
listOf(Pair(true, true), Pair(true, false), Pair(false, true), Pair(false, false)).map {
Row(it.first, it.second, f(it.first, it.second))
}
fun printTruthTable(f: (Boolean, Boolean) -> Boolean) {
println(listOf("a", "b", "result").joinToString("\t"))
truthTable(f).forEach {
println(listOf(it.a, it.b, it.result).joinToString("\t"))
}
}
data class Row(val a: Boolean, val b: Boolean, val result: Boolean)
class P46Test {
@Test fun `logical expressions`() {
assertThat(true.and_(true), equalTo(true))
assertThat(true.xor_(true), equalTo(false))
}
@Test fun `truth tables for logical expressions`() {
assertThat(truthTable(Boolean::and_), equalTo(listOf(
Row(true, true, true),
Row(true, false, false),
Row(false, true, false),
Row(false, false, false)
)))
assertThat(truthTable(Boolean::xor_), equalTo(listOf(
Row(true, true, false),
Row(true, false, true),
Row(false, true, true),
Row(false, false, false)
)))
assertThat(truthTable(Boolean::equ_), equalTo(listOf(
Row(true, true, true),
Row(true, false, false),
Row(false, true, false),
Row(false, false, true)
)))
printTruthTable { a, b -> a.and_(a.or_(b.not_())) }
assertThat(truthTable { a, b -> a.and_(a.or_(b.not_())) }, equalTo(listOf(
Row(true, true, true),
Row(true, false, true),
Row(false, true, false),
Row(false, false, false)
)))
}
}