【问题标题】:How to determine if two boolean expressions are the same如何判断两个布尔表达式是否相同
【发布时间】:2011-03-24 00:38:32
【问题描述】:

我需要确定两个不同的布尔表达式是否相同。例如:

S1 = a ∨ b
S2 = (a ∧ ¬b) ∨ b;

这两个其实是一样的。所以我需要检测它们是否相同。我正在使用 C#。

【问题讨论】:

  • 突然想到“为什么”这个词?告诉使用您要解决的实际问题...
  • 你的意思是,两个表达式得到相同的结果吗?
  • 这看起来不像 C#。您的意思是S1 = a | bS2 = a&!b | b,其中ab 是布尔值?
  • 我已将您的问题编辑为使用布尔代数符号,因为您的符号有点混乱:“∨”表示 OR,“∧”表示 AND,“¬”表示 NOT。不过,我并不是要踩你的脚趾,所以如果这令人困惑,请撤消我的编辑。
  • @MitchWheat 我目前正在尝试解决完全相同的问题。我正在构建一个自定义报告工具,它允许用户指定数据过滤器来生成图表。然后可以注释此图表。无论过滤器是如何应用的,我都需要将这些注释应用于同一个图表。因此,Name='Sam' AND (Team=1 OR Team=2) 的记录量与 (Team=1 OR Team=2) AND Name='Sam' 相同。这是一个非常基本的例子。我认为解决方案将涉及某种订购系统。

标签: c# boolean boolean-logic


【解决方案1】:

表达式S1S2 是等价的,如果(S1 == S2) 对所有a, b 组合都为真。这种重言式检查可以在C# 中实现为真值表枚举,如下所示:

static bool S1(bool a, bool b)
{
    return a || b;
}

static bool S2(bool a, bool b)
{
    return (a && !b) || b;
}

static void Main(string[] args)
{
    bool[] tf = { true, false };
    bool bSame = true;

    foreach(bool a in tf)
        foreach(bool b in tf)
        {
            bSame = bSame && (S1(a, b) == S2(a, b));
        }

    Console.WriteLine("S1 {0} S2", bSame ? "==" : "!=");
}

【讨论】:

    【解决方案2】:

    检查 a 和 b 是否具有相同的布尔值

    private bool Equals(bool a, bool b) { 返回 !(a ^ b); }

    【讨论】:

      【解决方案3】:

      除非你真的,真的聪明,并且你的问题包含数百万个参数,否则我会说使用蛮力。

      您正在做的事情被称为“形式等价检查”,并且经常使用简化的有序二元决策图来完成,此时我正在撰写维基百科文章,但由于有人麻烦了这样做已经,他们来了。

      http://en.wikipedia.org/wiki/Formal_equivalence_checking

      http://en.wikipedia.org/wiki/Binary_decision_diagram

      ...而且我不知道存在 linq Expressions 命名空间。在这种情况下,也许我会接受伊万所说的。

      【讨论】:

        【解决方案4】:

        没有现成的方法可以做到这一点。你得到的最接近的是Expression.Reduce() 方法,它不会做你想要的减少。

        您将需要编写一个表达式解析器来简化,比如布尔表达式,然后编写一些逻辑来验证简化后的表达式是否相同。

        示例类(没有验证,只是获取表达式的框架:

        public class ExpressionTest {
            public bool AreExpressionsSame<T>(Expression<T>/*<Func<bool,bool,bool>>*/ expr1, Expression<T> expr2) {
                var expr1_reduced = expr1.Reduce();
                var expr2_reduced = expr2.Reduce();
                //at this point expr2_reduced is the same as it went it.
                return true;
            }
        
        
            public void AreExpressionSameShouldAcceptLambda() {
                ExpressionTest et = new ExpressionTest();
        
                et.AreExpressionsSame<Func<bool,bool,bool>>((a,b) => a || b, (a,b)=>a && b || b);
            }
        }
        

        【讨论】:

          【解决方案5】:

          我不确定我是否按照您的要求...如果这些是使用布尔值的表达式(即您示例中的 a 和 b 是布尔值),您可以为它们计算出真值表,如果每个案例都匹配,那么你的表达式是等价的。

          还有其他方法,但实施起来似乎相当简单。只需插入 a=true, b=true; a=真,b=假; a=假 b=真; a=false, b=false 看看你得到了什么。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-05-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-03-18
            相关资源
            最近更新 更多