【问题标题】:Is there logical loophole here?这里有逻辑漏洞吗?
【发布时间】:2016-04-16 03:01:23
【问题描述】:

我需要执行一段这样的代码

if(condition 1)
{
    set variable to false
}
else if (condition 2)
{
    set variable to false
} else {
    set variable to true
}

和这个一样

 if(!condition 1)
 {
   if(!condition2)
   {
     variable = true
   }
 }

这两者的结果在任何情况下都可以不同吗?有系统的证明吗?

【问题讨论】:

  • variable = !(condition 1) && !(condition 2)
  • 这与您在第二个变体中从未将变量设置为 false 不同。
  • 如果可以假设变量已经为假,那么是的,它们是相同的。证明将与嵌套分支与逻辑运算符的等价性有关。

标签: logic computer-science boolean-logic


【解决方案1】:

第二个 sn-p 几乎等同于第一个 - 如果您可以假设 variable 被初始化为 false 除非另有设置,这可能适用于某些编程语言,但可能是个坏主意,你最好在调用这个 sn-p 之前将它显式初始化为false

注意,顺便说一句,整个表达式可以通过使用逻辑运算符大大缩短:

variable = !(condition1) && !(condition2);

或者可以说更优雅:

variable = !(condition1 || condition2);

【讨论】:

    【解决方案2】:

    你的问题

    这两者的结果在任何情况下都可以不同吗?

    相当广泛,我可以想到至少四种情况,其中两个 sn-ps 的结果可能不同。正如其他人指出的那样,这是假设您的第二个示例之前是以下初始化:

    variable = false
    

    如果没有上面的初始化步骤,很多编程语言会创建variable而不自动初始化它,这意味着它的值是不确定的。

    在介绍完这四个案例后,我将在最后证明两个 sn-ps 中的逻辑是相同的。

    案例 1:评估条件时的副作用

    这些可能不同的第一个情况是编程语言是否允许在评估条件时出现“副作用”。

    例如,在 C 语言中,条件可能是赋值语句的结果,它可以改变被测试变量的状态。

    考虑以下示例。如果我们在两个sn-ps中将variable初始化为false,并且让条件1为((variable = !variable) == true)和条件2为((variable = !variable) == false)(这有改变variable的值的副作用),那么在以下 C 代码:

    bool variable1 = false;
    if (((variable1 = !variable1) == true)) {
        variable1 = false;
    }
    else if (((variable1 = !variable1) == false)) {
        variable1 = false;
    }
    else {
        variable1 = true;
    }
    
    bool variable2 = false;
    if (!((variable2 = !variable2) == true)) {
        if (!((variable2 = !variable2) == false)) {
            variable2 = true;
        }
    }
    

    结果将是variable1 == falsevariable2 == true,这说明了结果不同的情况。

    案例 2:重载赋值运算符

    在 C++ 语言中,赋值运算符 (=) 可以被重载,这意味着它的整个含义可以更改为与它看起来不同的东西。因此可以定义一个赋值运算符,其中

    variable = false;
    

    有时会导致variable 被分配值false,但在某些情况下会导致variable 实际上被分配值true。这是一个奇怪的例子,但你的问题是

    这两者的结果在任何情况下都可以不同吗?

    所以在这里我假设“任何情况”都允许将基本假设(例如variable = false 真正意味着variable = false)放在一边。不难想象一个赋值运算符可以被设计为导致两种情况产生不同结果的场景。有人可能会争辩说,我在这里的想法太过分了,但在现实世界中,我们拥有诸如 C++ 之类的语言,它们的行为有时确实与人们预期的不同。

    案例 3:条件对时间敏感

    一个给定的优化编译器可能会认为你的两个 sn-ps 是等效的,并且可能实际上将它们编译为相同的机器代码。大多数编译器可能更有可能为两个 sn-ps 生成不同的机器代码。如果机器代码不同,则两个 sn-ps 的执行时间可能不同。如果条件 2 测试计时器的值,则计时器在第一个 sn-p 测试时的值可能与第二个 sn-p 中的不同,这可能会产生不同的决定,从而产生variable 的结果不同。

    案例 4:多个线程

    在采用抢先式多任务处理的程序中,有时程序员会忘记他们不再在封闭系统中工作。如果一个任务是一个线程,并且如果variable 和/或构成条件 1 或条件 2 的元素在两个异步线程中是可写访问的,则任何一个 sn-p 都可能被另一个线程中断,改变被评估或设置的变量的状态,导致不可预测的结果。

    案例 5:没有技巧

    如果我们假设我们谈论的是一个封闭的静态系统,没有像上面那样的意外,并且你真正想要的只是一个简单的证明,证明两个 sn-ps 在逻辑上是等价的,那么创建一个真值表,考虑所有可能性:

             Inputs               Output
    Condition 1  Condition 2    "variable"
    -----------  -----------    ----------
       False        False          True
       False        True           False
       True         False          False
       True         True           False
    

    如果您通过两个代码 sn-ps 运行这些输入,我相信您会发现两个 sn-ps 将产生相同的结果,如上表中的输出列所示。这将作为两者相同的系统证明。

    此表和您的两个代码 sn-ps 恰好代表 NOR 函数的行为。

    【讨论】:

      猜你喜欢
      • 2010-11-07
      • 1970-01-01
      • 1970-01-01
      • 2018-09-13
      • 1970-01-01
      • 2021-11-02
      • 2022-11-15
      • 2020-01-19
      相关资源
      最近更新 更多