public void TestThe() { NumExpression n = new NumVariable("n"); var two = new NumConstant(2); NumExpression test = new NumThe("n", n == two); Assert.AreEqual("2", testAsync(test, 1000).Result); test = new NumThe("n", n == two + two); Assert.AreEqual("4", testAsync(test, 1000).Result); test = new NumThe("n", n + n == n * n); // not valid since it has two results, but we ignore this Assert.AreEqual("0", testAsync(test, 1000).Result); // Find the positive natural such that 2n=n^2 test = new NumThe("n", (logicLoop | (n + n == n * n) & (n > zero)) | logicLoop); Assert.AreEqual("2", testAsync(test, 1000).Result); // Should fail test = new NumThe("n", (n == zero) & (n > zero)); Assert.AreEqual(False, testAsync(test, 1000).Result); test = new NumThe("n", (logicLoop | n == new NumConstant(50) | logicLoop)); Assert.AreEqual("50", testAsync(test, 1000).Result); // Find the positive natural such that 2n=n^2 this time with logicFalse test = new NumThe("n", ((n + n == n * n) & (n > zero)) | logicFalse); Assert.AreEqual("2", testAsync(test, 1000).Result); test = new NumThe("n", (n == new NumConstant(50) | logicFalse)); Assert.AreEqual("50", testAsync(test, 1000).Result); }
public SortedSet <string> Visit(NumThe expression) { // 'the' is a binder, so it binds its variable var vars = Run(expression.Expression); vars.Remove(expression.VariableName); return(vars); }
public Expression Visit(NumThe expression) { if (expression.VariableName == VariableName) { return(expression); // variable is shadowed } else { var expr = (LogicExpression)expression.Expression.Accept(this); return(new NumThe(expression.VariableName, expr)); } }
public T Visit(NumThe expression) { expression.Expression.Accept(this); return(default(T)); }
public async Task <Value> Visit(NumThe expression) { // The idea here is similar to VisitNumExists, except this time we remember // which number we found. // The number we are currently up to int nextNum = 0; bool foundValue = false; List <Task <Value> > runningTasks = new List <Task <Value> >(); // Setup a new token source so we can cancel all the tasks we have created CancellationTokenSource tokenSource = new CancellationTokenSource(); // When this task is cancelled make sure all the descendent ones are cancelled too if (CancelToken != null) { CancelToken.Register(() => tokenSource.Cancel()); } // Store a mapping of tasks to their values Dictionary <Task <Value>, int> taskDictionary = new Dictionary <Task <Value>, int>(); while (!foundValue) { // See if we have been canceled. If so cancel everything if (CancelToken != null && CancelToken.IsCancellationRequested) { tokenSource.Cancel(); } // Clone the context Dictionary <string, Value> newContext = (from x in Context select x).ToDictionary(x => x.Key, x => x.Value); newContext[expression.VariableName] = new NumValue(nextNum); // Construct a new evaluator with an updated context ExpressionEvaluator nextEvaluator = new ExpressionEvaluator(newContext); nextEvaluator.CancelToken = tokenSource.Token; // Add the new evaluator to our list of tasks Task <Value> newTask = expression.Expression.Accept(nextEvaluator); runningTasks.Add(newTask); taskDictionary[newTask] = nextNum; // create a new delay task to add to the list Task <Value> delay = Delay <Value>(ExistsTimeout, CancelToken); runningTasks.Add(delay); // Run the tasks until one completes Task <Value> resultTask = await Task.WhenAny(runningTasks); // If it is not the delay task we have a true result, so return it if (resultTask != delay) { Value resultValue = await resultTask; runningTasks.Remove(resultTask); if (resultValue is BoolValue) { if (((BoolValue)resultValue).Value) { // cancel all running tasks tokenSource.Cancel(); return(new NumValue(taskDictionary[resultTask])); } else { // expression is false, so remove from dictionary taskDictionary.Remove(resultTask); } } else { throw new ArgumentException("For 'the' the predicate should have a logic value"); } } else // delay has fired, so remove it and loop to the next number { runningTasks.Remove(delay); nextNum++; } } throw new NotImplementedException("This code should not be reached"); }