化简复杂逻辑,编写紧凑的if条件语句(二):依据if子句顺序化简条件

化简复杂逻辑,编写紧凑的if条件语句》已经得出了跳、等、飞、异常的各自条件,方便起见这里重新贴一下。

  • 立即跃迁:!a && b && d
  • 等待跃迁:!a && b && !d
  • 飞往星区:!b && c || a && c
  • 抛出异常:a && !c || !b && !c

这四个条件已经是“全集”了,或起来等于True。

按照跳、等、飞、异常的顺序写if-else if-...else-end语句,则是这样的:

            if (!a && b && d)
            {
                //立即跃迁
            }
            else if (!a && b && !d)
            {
                //可以跃迁但跳跃门附近有船。
                //为避免撞船,等待一会儿
            }
            else if (!b && c || a && c)
            {
                //老老实实飞过去
            }
            else//a && !c || !b && !c
            {
                //异常
            }

可以发现,第一第二句if里,!a && b 是重复的。大多数人可能希望把它改成嵌套的if。

            if (!a && b)
            {
                if (d)
                { 
                    //立即跃迁
                }
                else//!d
                { 
                    //可以跃迁但跳跃门附近有船。
                    //为避免撞船,等待一会儿
                }
            }

这种方法诚然可行,但它是基于开发人员的直觉或经验,不是数学上的推导。当条件复杂时,人们就会晕头转向了。

问题

我这里使用正规的数学方法化简第二句if。把程序问题转化为数学问题,就是:已知!a && b && d=false,化简!a && b && !d。

解答(法1)

解决此类问题的一般方法是代入法。

 & \lnot a \wedge b \wedge \lnot d \\ =& \lnot a \wedge b \wedge \lnot d \wedge \mathbf{F} \\ =& \lnot a \wedge b \wedge \lnot d \wedge  \lnot a \wedge b \wedge d\\ =& \lnot a \wedge b

用Mathematica的话还是用BooleanMinimize方法。

问题的等价表述

还有另一种数学表述:已知\lnot(x \wedge y)\rightarrow \left [ (x \wedge \lnot y) \Leftrightarrow z \right ]是个永真式,求解z。这个式子的意思是在x && y==false的情况下, x && !y与z总是给出相同的值。

解答(法2)

先把式子化简,并变换为合取范式。


Mathematica 7.0里符号似乎在Basic Math Assistant窗口里没有,要用ESC equivESC打出。

尽量使z出现的次数减少,再手工变换一下。

 & (\lnot a \vee \lnot z) \wedge (a \vee \lnot b \vee d \vee z) \wedge (b \vee \lnot z) \\ =& (a \vee \lnot b \vee d \vee z) \wedge (\lnot a \vee \lnot z) \wedge(b \vee \lnot z) \\ =& (a \vee \lnot b \vee d \vee z) \wedge \left [  (\lnot a \wedge b)\vee \lnot z\right ] \\ =& \left [\lnot (\lnot a \wedge  b) \vee d \vee z \right ] \wedge \left [(\lnot a \wedge b)\vee \lnot z \right ] \\

如果要使其为永真式,则左右两个括号里都得是永真式。在左边配一下,z可以等于\lnot a \wedge  b\lnot d;在右边配一下,z可以等于\lnot a \wedge  b。所以,z等于\lnot a \wedge  b

这个方法疑似比较难凑。

化简if条件

已知!a && b && d = false,化简!a && b && !d。刚才已经算过了,得!a && b。

已知!a && b=false,化简!b && c || a && c。用法1,得(! a && b) || c。又!a && b=false,最后得c。

已知!a && b = c = false,化简a && !c || !b && !c。得True。

现在代码可以优化成

            if (!a && b && d)
            {
                //立即跃迁
            }
            else if (!a && b)
            {
                //可以跃迁但跳跃门附近有船。
                //为避免撞船,等待一会儿
            }
            else if (c)
            {
                //老老实实飞过去
            }
            else//a && !c || !b && !c
            {
                //异常
            }

还有个问题。if条件的先后顺序影响了语句的化简结果。什么样的顺序才能得出最简表达呢?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值