计算真值表
程序设计说明
本来想用 lisp 程序来写,他的写法是
(function arg1 arg2 ...)
S表达式不需要考虑优先级顺序,写起来比较简单
但是在这里有太多运算符,写成 lisp 很不方便
p∧¬(q→p (p ↔ q) → r p → (p ∨ ¬q ∨ r)
还好有 Julia ,他可以自定义运算符
首先将运算符作为一个函数定义(以下例子这样写是因为 + 在程序中是特殊符号,需要加一个 : 前缀来标识, Julia 语言的一个 feature)
function Base.:+(arg1::SomeType, arg2::SomeType) return arg1 * arg2 end
解释器就可以把以下语句
arg1 + arg2
解析为
Base:+(arg1, arg2)
如果是调用多次
arg1 + arg2 + arg3
可以看作先对前两个进行求值,得出结果,与第三个参数求值
实现细节
演示说明
这里给出一个演示的例子
print(TruthTable("(p ↔ q) → r", [:p, :q, :r], (p, q, r) -> (p ↔ q) → r))
需要自定义真值表的
- 标题
- 参数表
- 生成真值的逻辑函数
运算符定义
¬(p::Bool) = !p # negative ∧(p::Bool, q::Bool) = p && q #conjunction, use \wedge ∨(p::Bool, q::Bool) = p || q #disjunction, use \vee →(p::Bool, q::Bool) = begin #implication, use \rightarrow !(p == true && q == false) end ↔(p::Bool, q::Bool) = p == q #equivalence, use \leftrightarrow
这些函数我都是通过参考真值表写出来的,一开始看符号推演我都看懵了,他娘的什么玩样,要我死记硬背,还不如自己写一个
真值表结构
struct TruthTable caption::String params::Vector{Symbol} target::Function end
我为真值表定义了三个 field
- _caption__ 标题
- _target__ 计算出真值的函数定义
- _params__ 为 target 配套的参数列表,每个都是符号类型
计算真值并打印
Julia 语言中可以重载 print 函数来打印 TruthTable 结构体,通过访问 TruthTable 结构体
就可以查看对应的真值表
这里需要用到第三方库 DataFrames
function Base.print(truthTable::TruthTable) table = DataFrames.DataFrame() len = length(truthTable.params) rows = 2 ^ len logicTable = reshape(collect(Iterators.product(repeat([[true, false]], len)...)), rows) for (symbol, index) in Iterators.zip(truthTable.params, Iterators.countfrom(1, 1)) table[!, symbol] = map(nums -> nums[index], logicTable) end results = map(nums -> truthTable.target(nums...), logicTable) table[!, truthTable.caption] = results println(table) end
效果展示