Expression evaluator for C#/Python/Ruby - c#

We have semi-complicated expressions in the format:
"25 + [Variable1] > [Variable2]"
We need an expression evaluator to parse the expression and use a callback to ask for the variable values and work out the overall result of the expression. It has to be a callback as there are thousands of variables.
We need the usual math operators but also things like "if" etc. The richer the language the better.
We can use any language we want. Anyone have any suggestions?

Have you considered using Mono.CSharp.Evaluator? It seems like this in conjunction with an appropriatelly set InteractiveBaseClass would do the trick quite nicely, and with minimal effort.
Note that the following uses Mono 2.11.1 alpha.
using System;
using System.Diagnostics;
using Mono.CSharp;
using NUnit.Framework;
public class MonoExpressionEvaluator
{
[Test]
public void ProofOfConcept()
{
Evaluator evaluator = new Evaluator(new CompilerContext(new CompilerSettings(), new ConsoleReportPrinter()));
evaluator.InteractiveBaseClass = typeof (Variables);
Variables.Variable1Callback = () => 5.1;
Variables.Variable2Callback = () => 30;
var result = evaluator.Evaluate("25 + Variable1 > Variable2");
Assert.AreEqual(25 + Variables.Variable1 > Variables.Variable2, result);
Console.WriteLine(result);
}
public class Variables
{
internal static Func<double> Variable1Callback;
public static Double Variable1 { get { return Variable1Callback(); } }
internal static Func<double> Variable2Callback;
public static Double Variable2 { get { return Variable2Callback(); } }
}
}
Real shame it runs a little slow. For instance, on my i7-m620 it takes almost 8 seconds to run this 10,000 times:
[Test]
public void BenchmarkEvaluate()
{
Evaluator evaluator = new Evaluator(new CompilerContext(new CompilerSettings(), new ConsoleReportPrinter()));
evaluator.InteractiveBaseClass = typeof(Variables);
Variables.Variable1Callback = () => 5.1;
Variables.Variable2Callback = () => 30;
var sw = Stopwatch.StartNew();
for (int i = 1; i < 10000; i++)
evaluator.Evaluate("25 + Variable1 > Variable2");
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
00:00:07.6035024
It'd be great if we could parse and compile it to IL so we could execute it at .NET speeds, but that sounds like a bit of a pipe dream...
[Test]
public void BenchmarkCompiledMethod()
{
Evaluator evaluator = new Evaluator(new CompilerContext(new CompilerSettings(), new ConsoleReportPrinter()));
evaluator.InteractiveBaseClass = typeof(Variables);
Variables.Variable1Callback = () => 5.1;
Variables.Variable2Callback = () => 30;
var method = evaluator.Compile("25 + Variable1 > Variable2");
object result = null;
method(ref result);
Assert.AreEqual(25 + Variables.Variable1 > Variables.Variable2, result);
Variables.Variable2Callback = () => 31;
method(ref result);
Assert.AreEqual(25 + Variables.Variable1 > Variables.Variable2, result);
var sw = Stopwatch.StartNew();
for (int i = 1; i < 10000; i++)
method(ref result);
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
00:00:00.0003799
Oh my.
Need excel-like expression constructs like IF? Build your own!
[Test]
public void ProofOfConcept2()
{
Evaluator evaluator = new Evaluator(new CompilerContext(new CompilerSettings(), new ConsoleReportPrinter()));
evaluator.InteractiveBaseClass = typeof(Variables2);
Variables.Variable1Callback = () => 5.1;
Variables.Variable2Callback = () => 30;
var result = evaluator.Evaluate(#"IF(25 + Variable1 > Variable2, ""TRUE"", ""FALSE"")");
Assert.AreEqual("TRUE", result);
Console.WriteLine(result);
}
public class Variables2 : Variables
{
public static T IF<T>(bool expr, T trueValue, T falseValue)
{
return expr ? trueValue : falseValue;
}
}

Check out NCalc. It's .NET and should support your requirements.

Pure expression evaluators are actually pretty easy to write.
See this SO answer which shows expression evaluators in a dozen langauges. You should be able to adapt one of these:
Code Golf: Mathematical expression evaluator (that respects PEMDAS)
EDIT: Whoever dinged this obviously didn't go and examine the solutions there. Yes, there are a bunch that are crammed tight to meet the golf-rules (typically "smallest") but most of them are explained pretty clearly with a cleartext version of algorithm.

Well ... you need a language. You have C#, VB.Net, IronPython, IronRuby, and others.
Simple replace the open variables using regex (maybe you even know them ahead and just need a string.Replace) and then compile the script using CodeDOM (for C# or VB.Net) or use the DLR (IronPython, IronRuby). You can simply add the variables as method parameters in the method wrapper you use to encapsulate your code (for CodeDOM) or just inject the variables in the DLR.
Both variants we implemented in our team in business with less effort and reliable effort.
When you urgently regquire the callback, well the add to the solutions above a method which communicate with the host of the programming language with a name like ValueOf(string). So you can write
ValueOf("A") > ValueOf("B") - 10
Have fun.

http://code.google.com/p/bc-expression/
Handles variable lookup via a lambda or block callback.
Understands numeric, string and boolean constants.
Unary operators + - !
Operators || && < <= == != >= > + - * / %
Grouping with ( )
Raises an Expression::SyntaxError if there's a syntax error.

Related

evaluate relational operator from a string

I have relational expressions stored in a database, that i have as strings in an iOS app. I would like to evaluate the conditions within the strings in C#, similar to the logic in the following psudo code:
string str1= "x > 0";
string str2= "y < 1";
int x = 1;
int y=0;
if(str1 && str2)
{
//do stuff
}
If the expressions are simple like the one in the example, then you can simply parse them. But if you have more complex expressions in mind, then I recommend taking a look at C# Expression Trees. The documentation does a good job of explaining it.
A much easier method would be to use library like: https://github.com/davideicardi/DynamicExpresso
Use Afk Expression Library (Afk link)
and try following code it will solve your problem as I sorted out.
Required NameSpace
using Afk.Expression;
Your code for sending expression as string to library evaluator
string str1 = "x > 0";
string str2 = "y < 1";
int x = 10;
int y = 0;
var st1=str1.Replace("x",x.ToString());
var st2 = str2.Replace("y", y.ToString());
if (Eval(st2) && Eval(st1))
{
//checked
}
Eval Method evaluate mathematical and conditional expression
bool Eval(string st)
{
ExpressionEval eval = new ExpressionEval(st);
return Convert.ToBoolean(eval.Evaluate().ToString());
}
As well read for more other libraries that you can utilize for your as such problems.

Update string with interpolation for each using

I have code like this:
int i = 1;
string dynemicString = $"i = {i}";
while(i<10)
{
Console.WriteLine(i);
i++;
}
And I want to get result like this:
i = 1
i = 2
i = 3
...
How to do it?
int i = 1;
while(i<10)
{
Console.WriteLine($"i = {i}");
i++;
}
For more information read about String Interpolation
If you want a more tokenized way of doing this, use String.Format
int i = 1;
string dynemicString = "i = {0}";
while(i<10)
{
Console.WriteLine(string.Format(dynemicString,i));
i++;
}
Here's an alternative approach to TheGeneral's answer. I'm not suggesting using it, but I find it an "interesting" idea just for the sake of learning a bit more about how string interpolation works.
When an interpolated string literal is converted to a string, all the expressions are immediately evaluated and the string is formatted. The string can't change afterwards.
When an interpolated string literal is converted to a FormattableString, the expressions are evaluated, but the string formatting isn't performed. Instead, the results of all the expressions are stored for later formatting. Every time you call ToString on a FormattableString, the formatting is performed again.
So, we can make it dynamic by making the same values (as evaluated initially) return different strings when string formatting happens. One simple - but really ugly - way of doing that is to use a delegate to capture i, and then put the delegate in a wrapper that overrides ToString and executes the delegate each time. Here's a complete example of that:
// CODE FOR EDUCATIONAL PURPOSES ONLY. DON'T USE IN PRODUCTION!
using System;
public class FuncWrapper
{
private readonly Func<string> func;
public FuncWrapper(Func<string> func) =>
this.func = func;
public override string ToString() => func();
}
class Test
{
static void Main()
{
int i = 1;
// Capture i in a delegate; each time the delegate
// is executed, you'll get a different value. Each
// time ToString is called, the delegate will be called
var wrapper = new FuncWrapper(() => i.ToString());
FormattableString dynamicString = $"i = {wrapper}";
while (i < 10)
{
Console.WriteLine(dynamicString);
i++;
}
}
}
Output:
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9

Compiled C# lambda expression performance with imbrication

Considering this class:
/// <summary>
/// Dummy implementation of a parser for the purpose of the test
/// </summary>
class Parser
{
public List<T> ReadList<T>(Func<T> readFunctor)
{
return Enumerable.Range(0, 10).Select(i => readFunctor()).ToList();
}
public int ReadInt32()
{
return 12;
}
public string ReadString()
{
return "string";
}
}
I try to generate the following call with a compiled lambda expression tree:
Parser parser = new Parser();
List<int> list = parser.ReadList(parser.ReadInt32);
However, the peformance is not quite the same...
class Program
{
private const int MAX = 1000000;
static void Main(string[] args)
{
DirectCall();
LambdaCall();
CompiledLambdaCall();
}
static void DirectCall()
{
Parser parser = new Parser();
var sw = new Stopwatch();
sw.Start();
for (int i = 0; i < MAX; i++)
{
List<int> list = parser.ReadList(parser.ReadInt32);
}
sw.Stop();
Console.WriteLine("Direct call: {0} ms", sw.ElapsedMilliseconds);
}
static void LambdaCall()
{
Parser parser = new Parser();
var sw = new Stopwatch();
sw.Start();
for (int i = 0; i < MAX; i++)
{
List<int> list = parser.ReadList(() => parser.ReadInt32());
}
sw.Stop();
Console.WriteLine("Lambda call: {0} ms", sw.ElapsedMilliseconds);
}
static void CompiledLambdaCall()
{
var parserParameter = Expression.Parameter(typeof(Parser), "parser");
var lambda = Expression.Lambda<Func<Parser, List<int>>>(
Expression.Call(
parserParameter,
typeof(Parser).GetMethod("ReadList").MakeGenericMethod(typeof(int)),
Expression.Lambda(
typeof(Func<int>),
Expression.Call(
parserParameter,
typeof(Parser).GetMethod("ReadInt32")))),
parserParameter);
Func<Parser, List<int>> func = lambda.Compile();
Parser parser = new Parser();
var sw = new Stopwatch();
sw.Start();
for (int i = 0; i < MAX; i++)
{
List<int> list = func(parser);
}
sw.Stop();
Console.WriteLine("Compiled lambda call: {0} ms", sw.ElapsedMilliseconds);
}
}
These are the results in milliseconds on my computer :
Direct call: 647 ms
Lambda call: 641 ms
Compiled lambda call: 5861 ms
I don't understand why the compiled lambda call is so slow.
And I forgot to say that my test is run in release mode with the "Optimize Code" option enabled.
Update: Changed benchmarking based on DateTime.Now to Stopwatch.
Does anyone know how to tweak the lambda expression to obtain a better performance in the compiled lambda call ?
The test is invalid for two reasons:
DateTime.Now isn't accurate enough for micro-benchmarking short tests.
Use the Stopwatch class instead. When I do so, I get the following results (using MAX = 100000), in milliseconds:
Lambda call: 86.3196
Direct call: 74.057
Compiled lambda call: 814.2178
Indeed, the "direct call" is faster than the "lambda call", which makes sense - the "direct call" involves calls to a delegate that refers directly to a method on a Parser object. The "lambda call" requires a call to a delegate that refers to a method on a compiler-generated closure object, which in turn calls the method on the Parser object. This extra indirection introduces a minor speed-bump.
The "Compiled lambda call" isn't the same as the "Lambda call"
The "Lambda" looks like this:
() => parser.ReadInt32()
whereas the "Compiled lambda" looks like this:
parser => parser.ReadList(() => parser.ReadInt32())
There's an extra step in there: To create the embedded delegate for the inner lambda. In a tight loop, this is expensive.
EDIT:
I went ahead and inspected the IL of the "lambda" vs the "compiled lambda" and decompiled them back to "simpler" C# (see: Viewing the IL code generated from a compiled expression).
For the "non compiled" lambda, it looks like this:
for (int i = 0; i < 100000; i++)
{
if (CS$<>9__CachedAnonymousMethodDelegate1 == null)
{
CS$<>9__CachedAnonymousMethodDelegate1 = new Func<int>(CS$<>8__locals3.<LambdaCall>b__0);
}
CS$<>8__locals3.parser.ReadList<int>(CS$<>9__CachedAnonymousMethodDelegate1);
}
Note that a single delegate is created once and cached.
Whereas for the "compiled lambda", it looks like this:
Func<Parser, List<int>> func = lambda.Compile();
Parser parser = new Parser();
for (int i = 0; i < 100000; i++)
{
func(parser);
}
Where the target of the delegate is:
public static List<int> Foo(Parser parser)
{
object[] objArray = new object[] { new StrongBox<Parser>(parser) };
return ((StrongBox<Parser>) objArray[0]).Value.ReadList<int>
(new Func<int>(dyn_type.<ExpressionCompilerImplementationDetails>{1}lambda_method));
}
Note that although the "outer" delegate is created only once and cached, a new "inner" delegate is created on every iteration of the loop. Not to mention other allocations for the object array and the StrongBox<T> instance.
The primary reason the compiled lambda is slower is because the delegate is created over and over again. Anonymous delegates are a special breed: they are only used in one location. So the compiler can do some special optimizations, like caching the value the first time the delegate is called. This is what is happening here.
I was not able to reproduce the large difference between the direct call and the lambda call. In fact, in my measurements the direct call is slightly faster.
When doing benchmarks like this, you may want to use a more accurate timer. The Stopwatch class in System.Diagnostics is ideal. You may also want to increase your number of iterations. The code as is only runs for a few milliseconds.
Also, the first of the three cases will incur a slight overhead from JIT'ing the Parser class. Try running the first case twice and see what happens. Or better still: use the number of iterations as a parameter in each method, and call each method first for 1 iteration, so they all start on a level playing field.

Call a delegate without specifying delegate's parameter

I have two similar functions I hope to refactor to remove duplication:
IEnumerable<TotalType> GetTotalForMonths(string id, DateTime lastTotalDate)
{
for (int i = 0; lastTotalDate.AddMonths(i + 1) <= DateTime.Now; i++)
{
var totalStartDate = new DateTime(lastTotalDate.AddMonths(i).Year, lastTotalDate.AddMonths(i).Month, 1);
var totalEndDate = totalStartDate.AddMonths(1);
var total = this.GetTotal(id, totalStartDate, totalEndDate);
yield return new TotalType(id, total, new TimeInterval(totalStartDate, totalEndDate));
}
}
The other does the same thing for days. I hope to pass in a delegate to generic-ize the particular duration (days, months, etc). I tried passing in Func<DateTime, DateTime> addTime, which works well, except that I don't want to specify addTime's arg value.
Suggestions?
var byMonths = GetTotal(123, yourDate, (d, i) => d.AddMonths(i));
var byDays = GetTotal(456, anotherDate, (d, i) => d.AddDays(i));
// ...
IEnumerable<TotalType> GetTotal(
string id, DateTime lastTotalDate, Func<DateTime, int, DateTime> adder)
{
for (int i = 0; adder(lastTotalDate, i + 1) <= DateTime.Now; i++)
{
var temp = adder(lastTotalDate, i);
var totalStartDate = new DateTime(temp.Year, temp.Month, 1);
var totalEndDate = adder(totalStartDate, 1);
var total = this.GetTotal(id, totalStartDate, totalEndDate);
var interval = new TimeInterval(totalStartDate, totalEndDate);
yield return new TotalType(id, total, interval);
}
}
I'm not sure if I understood your question correctly, but if you want to pass AddMonth method as an argument, without specifying the receiver object, you can construct a lambda:
GetTotal(id, lastDate, (dt, num) => dt.AddMonth(num))
to call the "genericized" function.
You need to declare the function as:
IEnumerable<TotalType> GetTotal(string id, DateTime lastTotalDate,
Func<DateTime, int, DateTime> adder)
What you're seeking to do is called "Currying". I have a pattern which I use in vb.net for that purpose; I'm not sure it's the best pattern, but it should be adaptable to C# without too much trouble. Note that while using lambda expressions will limit your ability to use edit-and-continue, use of a curry factory will pose no such restriction.
Here's a link to my question: What is the best pattern to curry delegate parameters (using .NET 2.0 or later)?
That should translate nicely into C#; any time you see parentheses starting with "(Of", replace them with angle brackets; "ByRef Foo As Bar" and "Dim Foo As Bar" both become "Bar Foo".

Predicates and lambda expression

I have recently moved to .net 3.0 (windows forms, C#). I want to know more about predicates and lambda expressions. Where should we use them? Do they improve performance? and how do they work internally. Thanks.
If you search Stack Overflow you'll find about a thousand answers explaining what they're for. In short - a lambda is a way of writing an anonymous method at the point where you want to pass it to another method. Technically the same as the delegate syntax for an anonymous method, although with added powers of type inference so you don't need to state the parameter types. A predicate is a method that accepts some value and returns a bool - an example would be the argument to Where.
A lambda that doesn't refer to any external variables gets turned into a private static method with a made-up name. If it refers to instance members of the enclosing class, it becomes an instance method. If it refers to local variables, those variables get "hoisted" into being fields of a compiler-generated class that is allocated when the enclosing method starts running, and the lambda's body becomes a method in that new class.
As for performance, they don't make that much difference. They involve the creation of temporary objects, but I find that these are collected extremely efficiently by the GC.
If you want to study the different versions of C# and how they different .My suggestion is read the book C.Sharp.in.Depth by jon skeet . This will give you the better understanding of new versions
Do they improve performance? and how
do they work internally. Thanks.
For the most part, you'll never notice the performance hit. However, there are some pathological cases which will kill performance, namely overzealous use of fixed point combinators.
Its a well-known trick that we can use the Y-combinator to write recursive lambda functions, however consider the following code:
using System;
using System.Diagnostics;
namespace YCombinator
{
class Program
{
static Func<T, U> y<T, U>(Func<Func<T, U>, Func<T, U>> f)
{
return f(x => y<T, U>(f)(x));
}
static int fibIter(int n)
{
int fib0 = 0, fib1 = 1;
for (int i = 1; i <= n; i++)
{
int tmp = fib0;
fib0 = fib1;
fib1 = tmp + fib1;
}
return fib0;
}
static Func<int, int> fibCombinator()
{
return y<int, int>(f => n =>
{
switch (n)
{
case 0: return 0;
case 1: return 1;
default: return f(n - 1) + f(n - 2);
}
});
}
static int fibRecursive(int n)
{
switch (n)
{
case 0: return 0;
case 1: return 1;
default: return fibRecursive(n - 1) + fibRecursive(n - 2);
}
}
static void Benchmark(string msg, int iterations, Func<int, int> f)
{
int[] testCases = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20 };
Stopwatch watch = Stopwatch.StartNew();
for (int i = 0; i <= iterations; i++)
{
foreach (int n in testCases)
{
f(n);
}
}
watch.Stop();
Console.WriteLine("{0}: {1}", msg, watch.Elapsed.TotalMilliseconds);
}
static void Main(string[] args)
{
int iterations = 10000;
Benchmark("fibIter", iterations, fibIter);
Benchmark("fibCombinator", iterations, fibCombinator());
Benchmark("fibRecursive", iterations, fibRecursive);
Console.ReadKey(true);
}
}
}
This program prints out:
fibIter: 14.8074
fibCombinator: 61775.1485
fibRecursive: 2591.2444
fibCombinator and fibRecursive are functionally equivalent and have the same computational complexity, but fibCombinator is a full 4100x slower due to all of the intermediate object allocations.

Categories