函数的数学等式
本文关键字:int 函数 | 更新日期: 2023-09-27 18:04:42
我有一个实现ISequence
的Sequence
类型。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的回答标记为接受。然而,这项工作还没有完成。点击这里查看第二部分
你的问题有两个部分,"如何分解表达式并对其求值"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中填写"你的第二个问题"