public void TestFreeVariables() { SortedSet <string> variables; LogicExpression test = new NumExists("n", n == m); FreeVariableLister lister = new FreeVariableLister(); variables = test.Accept(lister); Assert.AreEqual(1, variables.Count); Assert.IsTrue(variables.Contains("m")); test = new NumExists("x", n == n); lister = new FreeVariableLister(); variables = test.Accept(lister); Assert.AreEqual(1, variables.Count); Assert.IsTrue(variables.Contains("n")); test = (new NumThe("n", n == two)) == two; lister = new FreeVariableLister(); variables = test.Accept(lister); Assert.AreEqual(0, variables.Count); //Assert.IsTrue(lister.Variables.Contains("n")); // this test shows that the original method does not work test = n == n & new NumExists("n", n == two); lister = new FreeVariableLister(); variables = test.Accept(lister); Assert.AreEqual(1, variables.Count); }
public void TestExists() { NumExpression n = new NumVariable("n"); var two = new NumConstant(2); var hundred = new NumConstant(100); Expression test = new NumExists("n", n == two); Assert.AreEqual(True, testAsync(test, 1000).Result); Expression test2 = new NumExists("n", n == n + n); Assert.AreEqual(True, testAsync(test2, 1000).Result); Expression test3 = new NumExists("n", n == n + two); Assert.AreEqual(False, testAsync(test3, 1000).Result); Expression test4 = new NumExists("n", n == hundred); // should take 1 sec to find (100 * 10ms) Assert.AreEqual(True, testAsync(test4, 2000).Result); Expression test5 = new NumExists("n", two < n); Assert.AreEqual(True, testAsync(test5, 2000).Result); Expression test6 = new NumExists("n", n < n); Assert.AreEqual(False, testAsync(test6, 1000).Result, "test6"); }
public SortedSet <string> Visit(NumExists expression) { // Since this is a quantifier it binds a variable, which is no longer free. // Note: find the free variables before removing them! var vars = Run(expression.Expression); vars.Remove(expression.VariableName); return(vars); }
public Expression Visit(NumExists expression) { if (expression.VariableName == VariableName) { return(expression); // variable is shadowed } else { var expr = (LogicExpression)expression.Expression.Accept(this); return(new NumExists(expression.VariableName, expr)); } }
public void TestSubstitution() { var subst = new VariableSubstituter("n", two); var result = n.Accept(subst); Assert.AreEqual("2", testAsync(result, 200).Result); result = zero.Accept(subst); Assert.AreEqual("0", testAsync(result, 200).Result); var exists = new NumExists("n", n == n); result = exists.Accept(subst); Assert.AreEqual(True, testAsync(result, 200).Result); var test = new Apply(new LambdaExpression("n", n == n), two); Assert.AreEqual(True, testAsync(test, 200).Result); // test that substitution avoids explosions var test2 = new Apply(new LambdaExpression("x", logicTrue), logicLoop); Assert.AreEqual(True, testAsync(test2, 200).Result); var test3 = new Apply(new LambdaExpression("x", logicLoop), logicTrue); Assert.AreEqual(Loop, testAsync(test3, 500).Result); var test4 = new Apply(new LambdaExpression("x", x & logicTrue), logicLoop); Assert.AreEqual(Loop, testAsync(test4, 500).Result); var test5 = new Apply(new LambdaExpression("x", x | logicTrue), logicLoop); Assert.AreEqual(True, testAsync(test5, 500).Result); }
public T Visit(NumExists expression) { expression.Accept(this); return(default(T)); }
public async Task <Value> Visit(NumExists expression) { // The idea here is to continually spawn off tasks evaluating the expression // in the environment where the variable is bound to first 0, then 1, then 2, ... // When one of these completes we have true. Otherwise we loop forever. // 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 result, so check to see if it is true if (resultTask != delay) { Value result = await resultTask; // Remove the tasks from the running runningTasks.Remove(resultTask); if (result is BoolValue) { if (((BoolValue)result).Value) { // We have a true result. tokenSource.Cancel(); // cancel all tasks which were spawned return(result); } } else { throw new ArgumentException("In exists the predicate should evaluate to a BoolValue"); } } 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"); }