函数的数学等式

本文关键字:int 函数 | 更新日期: 2023-09-27 18:04:42

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

我想根据两个Func s的相等性来检查两个Sequence对象的相等性。我开始四处浏览,有一些帖子使用Expression s来分解lambda和Func s来实现相等,但我说的是数学上的相等。

换句话说,x => 2 * x应该等于c => c * 2,以及任何数学表达式的变化,比如Math。有多个操作符。如果我能让它工作,我可以比较Sequence s的数学等式。

我试着写我自己的扩展方法:

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> s。这能做到吗?有人有解决办法吗?我需要改变存储第n项公式的方法吗?我反对检查输出,因为序列可能对某些输出相等,而不是对所有输出相等。

如果我需要发布任何序列代码,我会。

更新:我决定将Scott的回答标记为接受。然而,这项工作还没有完成。点击这里查看第二部分

函数<int, int>的数学等式

你的问题有两个部分,"如何分解表达式并对其求值"answers"如何检查两个表达式是否表示相同的逻辑运算"。

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

您需要做的是创建一个ExpressionVisitor,并通过覆盖VisitBinary并构建所有操作的列表来遍历每个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中填写"你的第二个问题"