I am looking for an algorithm or approach to evaluate mathematical expressions that are stated as string. The expression contains mathematical components but also custom functions. I look to implement said algorithm in C#/.Net.
I am aware that Roslyn allows me to evaluate an expression of the kind
"var value = 3+5*11-Math.Sqrt(9);"
I am also familiar how to use "node re-writing" in order to accomplish avoidance of variable declarations or fully qualified function names or the omission of the trailing semicolon in order to evaluate
"value = 3+5*11-Sqrt(9)"
However, what I want to implement on top of this is to offer custom script functions such as
"value = Ratio(A,B)", where Ratio is a custom function that divides each element in vector A by each element in vector B and returns a same length vector.
or
"value = Sma(A, 10)", where Sma is a custom function that calculates the simple moving average of vector/timeseries A with a lookback window of 10.
Ideally I want to get to the ability to provide more complexity such as
"value = Ratio(A,B) * Pi + 0.5 * Spread(C,D) + Sma(E, lookback)", whereby the parsing engine would respect operator precedence and build a parsing tree in order to fetch values, required to evaluate the expression.
I can't wrap my head around how I could solve such kind of problem with Roslyn.
What other approaches are out there to get me started or am I missing features that Roslyn offers that may assist in solving this problem?
Assuming that all your expressions are valid C# expressions you can make use of Roslyn in multiple ways.
You could use Roslyn only for parsing. SyntaxFactory.ParseExpression would give you the syntax tree of an expression. Note that your first (var v = expr;) example is not an expression, but a variable declaration. However v = expr is an expression, namely an AssignmentExpressionSyntax. Then you could traverse this AST, and do with each node what you want to do, basically you'd write an interpreter. The benefit of this approach is that you don't have to write your own parser, walking an AST is very simple, and this approach would be flexible, as defining what you do with "unknown" methods would be perfectly up to you.
Use Roslyn for evaluation too. This can be done in multiple flavors: either putting together a valid C# file, and compiling that into an assembly, or you could go through the Scripting API. This approach would basically require a class library that contains the implementation of all your extra methods, like Sma, Spread, ... But these would also be needed in some form in the first approach, so it's not really an extra effort.
If the only goal is to evaluate the expression, then I would go with the 2nd approach. If there are extra requirements (which you haven't mentioned) like being able to let's say produce a simplified form of an expression, then I'd consider the first solution.
If you find a library that does exactly what you need (and the perf is good, and you don't mind the dependency on 3rd party tools, ...), I'd go with that. MathParser.org-mXparser suggested in the comment seems pretty much what you're looking for.
Related
I have a use case in Q# where I have qubit register qs and need to apply the CNOT gate on every qubit except the first one, using the first one as control. Using a for loop I can do it as follows:
for (i in 1..Length(qs)-1) {
CNOT(qs[0], qs[i]);
}
Now, I wanted to give it a more functional flavor and tried instead to do something like:
ApplyToEach(q => CNOT(qs[0], q), qs[1..Length(qs)-1]);
The Q# compiler does not accept an expression like this, informing me that it encountered an unexpected code fragment. That's not too informative for my taste. Some documents claim that Q# supports anonymous functions a'la C#, hence the attempt above. Can anybody point me to a correct usage of lambdas in Q# or dispel my false belief?
At the moment, Q# doesn't support lambda functions and operations (though that would be a great feature request to file at https://github.com/microsoft/qsharp-compiler/issues/new/choose). That said, you can get a lot of the functional flavor that you get from lambdas by using partial application. In your example, for instance, I could also write that for loop as:
ApplyToEach(CNOT(Head(qs), _), Rest(qs));
Here, since CNOT has type (Qubit, Qubit) => Unit is Adj + Ctl, filling in one of the two inputs as CNOT(Head(qs), _) results in an operation of type Qubit => Unit is Adj + Ctl.
Partial application is a very powerful feature, and is used all throughout the Q# standard libraries to provide a functional way to build up quantum programs. If you're interested in learning more, I recommend checking out the docs at https://learn.microsoft.com/quantum/language/expressions#callable-invocation-expressions.
The request:
I'd like to be able to write an analyzer that can provide a proxy value for a certain expression and trigger a re-parsing of the document.
The motivation:
Our code is littered with ABTests that can be either in a deployed or active state with a control and variant group.
Determining a test's state is done through a database lookup.
For the tests that are deployed with the control group, any statement of the following form will evaluate to false:
if(ExperimentService.IsInVariant(ABTest.Test1))
{
}
I'm trying to provide tooling to make this easier to deal with at develop time by greying it out in this scenario.
As it is, this is fairly limited and not robust because I basically have to play parser myself.
What if the actual code is
if(!ExperimentService.IsInVariant(ABTest.Test1))
or
if(ExperimentService.IsInVariant(ABTest.Test1) || true)
or
var val = ..... && (ExperimentService.IsInVariant(ABTest.Test1);
if(val){
// val is always going to be false if we deployed control.
}
A possible approach I could see provided is by allowing us to write analyzers that are fired once and rewrite the tree before the actual IDE parsing happens (or, well, just parse it a second time).
These should only fire once and allow us to replace a certain expression with another. This would allow me to swap all of these experiment calls for true and false literals.
As a result, these sections could benefit from all the other IDE features such as code greying for unreachable code but also more intricate ones like a variable that will never have a different value
Obviously this is just an example and I'm not sure how feasible it is. Any suggestions for a proper feature or something that already exists are more than welcome.
I don't think there's an approach that doesn't have a compromise.
ReSharper doesn't support rewriting the AST before analysis - that would just rewrite the text in the file.
You could write an analyser that greys out the code, by applying a "dead code" highlight to the contents of the if block, but as you say, you'd need to parse the code and analyse control flow in order to get it correct, and I think that would be very difficult (ReSharper does provide a control flow graph, so you could walk it, but it would be up to you to A. find the return value of IsInVariant and B. trace that value through whatever conditions, && or || statements until you find an appropriate if block).
Alternatively, you could mark the IsInVariant method with the ContractAnnotation attribute, something like:
[ContractAnnotation("=> false")]
public bool IsInVariant(string identifier)
{
// whatever...
}
This will tell ReSharper's analysis that this method always returns false (you can also say it will return true/false/null/not null based on specific input). Because it always returns false, ReSharper will grey out the code in the if statement, or the else branch if you do if (!IsInVariant(…)).
The downside here is that ReSharper will also add a warning to the if statement to tell you that the expression always returns false. So, it's a compromise, but you could change the severity of that warning to Hint, so it's not so intrusive.
This is not enough to really warrant the bounty, but one solution that might apply from the developer documentation is to create a custom language and extend the basic rules.
You said
I'm trying to provide tooling to make this easier to deal with at develop time by greying it out in this scenario.
Greying out the corresponding parts might just be done by altering syntax highlighting rules.
See this example for .tt files.
Is there any solution similar to [PostSharp] - [Infuse - A Precompiler for C#] that let me modify code at compile time ?
The below is a pseudo code.
[InterceptCallToConstructors]
void Method1(){
Person Eric = new Person("Eric Bush");
}
InterceptCallToConstructors(ConstructorMethodArgs args){
if(args.Type == typeof(Person))
if(PersonInstances++ > 10 ) args.ReturnValue = null;
}
In this example we see the Eric should not contain a new Person class if more than 10 Person are created.
After some research I found two solution PostSharp and Infuse.
With Infuse it's very complicated and hard to detect how many instance of Person are made how ever with PostSharp it's one line code to detect.
I have tried to go AOP with PostSharp but PostSharp currently doesn't support to intercept Call To Constructor Aspect.
As far as I read Roslyn doesn't support to modify code at compile time.
This would be a "custom preprocessor" answer, that modifies the source code to achieve OP's effect.
Our DMS Software Reengineering Toolkit with its C# Front End can do this.
DMS provides for source to source transformations, with the transformations coded as
if you see *this*, replace it by *that*
This is written in the form:
rule xxx pattern_parameters
this_pattern
-> that_pattern ;
The "->" is pronounced "replace by: :-}
DMS operates on ASTs, so includes a parsing step (text to ASTs), a tree transformation step, and a prettyprinting step that produces the final answer (ASTs to text).
OP's seems to want to modify the constructor call site (he can't modify the constructor; there's no way to get it to return "null"). To accomplish OP's, task, he would provide DMS the following source-to-source transformation specification:
default domain CSharp~v5; -- says we are working with C# syntax (and need the C# front end)
rule intercept_constructor(c: IDENTIFIER, a:arguments): expression
" new \c (\a) "
-> " \c.PersonInstances==10?null:(PersonInstances++,new \c (\a)) "
if c == "Person"; -- one might want to force c to be on some qualified path
What the rule does is find matching constructor call syntax of arbitrary form, and replace it by a conditional expression that check's OP's precondition, returning null if there are too many Person instances (we fix a bug in OP's spec here; he appears to increment the count whether new Person instance is created or not, surely not his intention). We have to qualify the PersonInstance's location; it can't just be floating around in the ether. In this example I'm proposing it is a static member of the class.
The details: each rule has a name ("intercept_constructor", stolen from OP). It refers to a syntactic category ("expression") with syntactic shape "new \c (\a)", forcing it to match only constructor calls that are expressions. The quotes in the rule are meta-quotes; they distinguish the syntax of the rule language from the syntax of the targeted language (C# in this case). The backslashes are meta-escapes; \c in meta-quotes is the same think in the rule as c outside the meta-quotes, similarly for \a.
In a really big system there may be several Person classes. We want to make sure we get right one; one might need to qualify the referenced class as being a specific by by providing a path. OP hints at this with the annotation. If one wanted to check that an annotation existed on the containing method, one would need custom special predicate to ask for that. DMS provides complete facilities for coding such a predicate, including complete access the the AST, so the predicate can climb up or down in its search for a matching annotation.
If you're running on top of the KRuntime (-> ASP.NET 5) you can hook into the compilation by implementing the ICompileModule assembly neutral interface.
I'd recommend loooking at:
the aop example in the repo
this nice writeup
i am not sure if this is a typical stackoverflow question, but i am working on an application where i should constantly examine some conditions (for example if a certain variable's value is over a threshold). Conditions can be changed at any time and preferably from outside the code.
People suggested i should be using expression parsers, but i still don't understand what advantage do they provide me over basic mathematical operations provided by .NET.
Do you recommend a good .NET expression parser?
I think you need Dynamic LINQ. You can pass the conditions as strings.
Here is a blog post about that by ScottGu: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
I found this by a similar question: Dynamic WHERE clause in LINQ
An expression parser would offer more flexibility. Your expressions could be written as formulars in strings and they could be application data instead of harcoded classes/methods/whatever.
You could do things like:
// Assign an action to an expression given as a string
ExpressionObserver.Add("(a+b+c)/2 > x-y", () => { DoSomething(); });
Or:
// Replace the old expression by something written by the user in the UI
someExpressionActionAssignment.Expression = MyLineEdit1.Text;
But I do not know if the added complexity of all this really pays off in your case. If you only have a few simple expressions then it's probably overkill.
I just came across the concept of expression trees which I have heard multiple times. I just want to understand what is meant by an expression tree and its purpose.
I would love it if someone could also direct me to simple explanations and samples of use.
An Expression Tree is a data structure that contains Expressions, which is basically code. So it is a tree structure that represents a calculation you may make in code. These pieces of code can then be executed by "running" the expression tree over a set of data.
A great thing about expression trees is that you can build them up in code; that is, you build executable code (or a sequence of steps) in code. You can also modify the code before you execute it by replacing expressions by other expressions.
An Expression is then a function delegate, such as (int x => return x * x).
See also http://blogs.msdn.com/b/charlie/archive/2008/01/31/expression-tree-basics.aspx