Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# resolve "(true and true) or (true or false)"

C#: I have a string variable that looks like this:

 string a = "(true and true) or (true or false)";

This can be anything, it can get more complex, like:

 string b = "((true and false) or (true or false) and not (true and false)) and false";

All i know is that it is correct. Cannot happen that this expression cannot be "evaluated".

Is there a way that I can somehow evaluate this? I would only like to know the outcome (result) of that string. This means I need "true" or "false" instead of this string.

I think I can make a parse method that does this, reducing the string step by step, until we got the final value, but I was wondering if there is a better approach.

like image 563
Ash Avatar asked Dec 02 '22 02:12

Ash


2 Answers

Expanding on Rob's comment, you can use runtime compilation in conjunction with C# 4.0 dynamic support and do something like this:

var expression = "(true and false) or (true or false)";

var helper = "" + 
    "using System; " + 
    "public class Expression {{ public bool Eval() {{ return {0}; }} }}";

var replaced = expression.Replace("and", "&&").Replace("or", "||");

var references = new string[] { "System.dll" };
var parameters = new CompilerParameters(references, "Test.dll");
var compiler = new CSharpCodeProvider();


var results = compiler.CompileAssemblyFromSource(
    parameters, 
    String.Format(helper, replaced));

dynamic exp = Activator.CreateInstance(
    results.CompiledAssembly.GetType("Expression"));

Console.WriteLine(exp.Eval());
like image 158
João Angelo Avatar answered Dec 18 '22 11:12

João Angelo


Something like this maybe?

string previous = string.Empty;
while (b != previous) 
{
     previous = b;
     b = b.Replace("true and false", "false");
     b = b.Replace("true and true", "true");
     b = b.Replace("false and true", "false");
     b = b.Replace("false and false", "false");
     b = b.Replace("false or false", "false");
     b = b.Replace("true or false", "true");
     b = b.Replace("true or true", "true");
     b = b.Replace("false or true", "true");
     b = b.Replace("(false)", "false");
     b = b.Replace("(true)", "true");
     b = b.Replace("not false", "true");
     b = b.Replace("not true", "false");
 }

Note that the specification allows ambigious formulations, such as these:

"false and false or true"
"false and true or true"

Both of these expressions are "true" if the and is evaluted first, and "false" if the or is evaluated first. Therefore, requireing parenthesis at every level would be better. Requiring left-to-right evaluation is another option, but that makes the code a bit more complex.

For those of you who may object to this style of solution for this style of problem, remember that some mathematicians believe that all of mathematics may be reduced to this sort of symbol manipulation. It is said that one of the main criticisms of Russell and Whitehead’s Principia Mathematica is that it embues the formulas with too much meaning.

like image 26
Jeffrey L Whitledge Avatar answered Dec 18 '22 10:12

Jeffrey L Whitledge