Func<int, int> 的数学等式

Mathematical Equality for Func<int, int>

我有一个 Sequence 类型实现了 ISequenceISequence 实现 IEnumerable<Element> 其中 Element 是另一种自定义类型。目前,我的 Sequence 类型将生成序列的第 N 项的指令存储为 Func<int, int>。这很方便,因为它允许我通过对 Func 的简单调用来调用 NTerm(int n),并使用 lambda 创建 Sequence。我想避免改变这种方法。

我想根据两个 Func 的相等性来检查两个 Sequence 对象的相等性。我开始四处浏览,有几个 posts 使用 Expressions 分解 lambdas 和 Funcs 用于相等,但我说的是数学相等。

In other words, x => 2 * x should equal c => c * 2, along with any variations of mathematical expressions, such as Math.Pow or more involved operators. If I can get that to work, I can compare Sequences for mathematical equality.

我尝试编写自己的扩展方法:

public static bool MathEquals(this Expression<Func<int, int>> f,
     Expression<Func<int, int>> g)

我不确定如何从那里开始。我写了一些基本的默认值:

if (ReferenceEquals (f, g)) return true;
if (f == null || g == null) return false;
if (f.NodeType != g.NodeType || f.Type != g.Type) return false;

但我需要检查两个 lambda 表达式的数学相等性,即两个 Func<int, int>。这可以做到吗?有没有人有办法解决吗?我是否需要更改存储第 N 项公式的方法?我反对检查输出,因为某些输出的序列可能相等,但并非全部。

如果我需要 post 任何序列代码,我会的。

更新: 我决定将斯科特的回答标记为已接受。然而,这项工作还没有完成。查看第二部分 here.

您的问题分为两部分,"How do I break apart a expression and evaulate it" 和 "How do I check that two expressions mean the same logical operation"。

我不知道第二部分怎么做,但我知道第一部分。

您需要做的是通过覆盖 VisitBinary 并构建所有操作的列表来创建 ExpressionVisitor and have it walk through each BinaryExpression

public class OperationParser : ExpressionVisitor
{
    public OperationParser()
    {
        Expressions = new List<BinaryExpression>();
    }

    public List<BinaryExpression> Expressions { get; private set; }  

    protected override Expression VisitBinary(BinaryExpression b)
    {
        Expressions.Add(b);

        return base.VisitBinary(b);
    }
}

那你会做

    Expression<Func<int, int>> expression1 = (x) => x + 2;
    Expression<Func<int, int>> expression2 = (y) => 2 + y;

    var parser1 = new OperationParser();
    parser1.Visit(expression1);

    var parser2 = new OperationParser();
    parser2.Visit(expression2);

    //TODO: write a way to compare parser1.Expressions to parser2.Expressions to see if they "mean the same thig"

您只需要在TODO中填写"your second question"