private SolverNode(IEnumerable<AbstractConstraint> constraints, IDictionary<IVariable, AbstractClosedVariable> closedVariables, SolverNode origin) { _debugOrigin = origin; if (origin != null) { origin._debugSuccessors++; } //var foldingVisitor = new ConstantFoldingVisitor(); var foldingVisitor = new PolynomialFoldingVisitor(); _constraints = constraints.Select(c => c.Accept(foldingVisitor, Ig.nore)).ToArray(); // !!!TOARRAY foreach (var c in _constraints) { c.SetDebugCreatingNodeIdIfMissing(DebugId); } _closedVariables = new SortedDictionary<IVariable, AbstractClosedVariable>(closedVariables); }
private void ResolveBacksubstitutions() { //var foldingVisitor = new ConstantFoldingVisitor(); var foldingVisitor = new PolynomialFoldingVisitor(); // The "ToArrays" are necessary because we modify _closedVariables below. Without them, // we get InvalidOperationExceptions telling us that the "Collection was modified." var varsWithValue = ClosedVariables.Values.OfType<VariableWithValue>().ToArray(); var varsWithBacksubstitutions = ClosedVariables.Values.OfType<VariableWithBacksubstitution>().ToArray(); while (varsWithBacksubstitutions.Any()) { if (!varsWithValue.Any()) { Debug.WriteLine("---- No complete backsubstitution possible ----"); foreach (var vb in varsWithBacksubstitutions) { Debug.WriteLine(vb); } throw new InvalidOperationException("No solution found - " + "there are more variables to substitute, but still open substitutions"); } var newVarsWithValue = new Dictionary<IVariable, VariableWithValue>(); foreach (var varWithValue in varsWithValue) { var newVarsWithBacksubstitutions = new List<VariableWithBacksubstitution>(); // We substitute each variable into all open backsubstitutions. //var rewriter = new RewritingVisitor(new Dictionary<IAbstractExpr, IAbstractExpr> // { { varWithValue.Variable, // Polynomial.CreateConstant(varWithValue.Value) // } }); var rewriter = new RewritingVisitor(varWithValue.Variable, Polynomial.CreateConstant(varWithValue.Value)); foreach (var varWithBacksub in varsWithBacksubstitutions) { IAbstractExpr rewritten = varWithBacksub.Expr .Accept(rewriter) .Accept(foldingVisitor); // If the result, after constant folding, is a constant, we have found a new solution value. // Otherwise, we still have a - maybe smaller - backsubstitution for this variable. if (rewritten is IConstant) { var result = new VariableWithValue(varWithBacksub.Variable, ((IConstant)rewritten).Value); newVarsWithValue.Add(varWithBacksub.Variable, result); ClosedVariables[varWithBacksub.Variable] = result; } else { var result = new VariableWithBacksubstitution(varWithBacksub.Variable, rewritten); newVarsWithBacksubstitutions.Add(result); } } newVarsWithBacksubstitutions.RemoveAll(v => ClosedVariables.ContainsKey(v.Variable) && ClosedVariables[v.Variable] is VariableWithValue); varsWithBacksubstitutions = newVarsWithBacksubstitutions.ToArray(); } varsWithValue = newVarsWithValue.Values.ToArray(); } }
private SolverNode CloseVariable(IVariable variable, IAbstractExpr expression, AbstractConstraint sourceConstraintToBeRemoved) { //var foldingVisitor = new ConstantFoldingVisitor(); var foldingVisitor = new PolynomialFoldingVisitor(); expression = expression.Accept(foldingVisitor); // Rewrite all constraints //var rewriter = new RewritingVisitor( // new Dictionary<IAbstractExpr, IAbstractExpr> { { variable, expression } }); var rewriter = new RewritingVisitor(variable, expression); IEnumerable<AbstractConstraint> rewrittenConstraints = Constraints.Except(sourceConstraintToBeRemoved) .Select(c => c.Accept(rewriter, Ig.nore)); // Create new variable->value knowledge or new backsubstition. var newBacksubstitutions = new Dictionary<IVariable, AbstractClosedVariable>(ClosedVariables) {{ variable, expression is IConstant ? (AbstractClosedVariable) new VariableWithValue(variable, ((IConstant) expression).Value) : new VariableWithBacksubstitution(variable, expression) }}; // Create new node. return new SolverNode(rewrittenConstraints, newBacksubstitutions, this); }
public void TestManyMinuses1() { IAbstractExpr a = P("x", 1, 2); IAbstractExpr b = a; var foldingVisitor = new PolynomialFoldingVisitor(); for (int i = 0; i < 4; i++) { // Apply double unary minus b = -(-b.C); Assert.AreEqual(a, b.Accept(foldingVisitor, Ig.nore)); } }
public void TestManyMinuses() { UnaryExpression a = new UnaryExpression(Polynomial.CreateNamedVariable("x"), new Sin()); AbstractExpr b = a.C * a; //new UnaryExpression(a, new Square()); IAbstractExpr[] exprs = new IAbstractExpr[] { a, b, new UnaryExpression(Polynomial.CreateNamedVariable("x"), new FormalSquareroot()), new UnaryExpression(Polynomial.CreateNamedVariable("x"), new PositiveSquareroot()), -a, a + b, a * b, a / b }; IAbstractExpr[] exprs2 = exprs; var foldingVisitor = new PolynomialFoldingVisitor(); for (int i = 0; i < 4; i++) { exprs2 = exprs2.Select(e => -(-e.C).C).ToArray(); for (int j = 0; j < exprs.Length; j++) { Assert.AreEqual(exprs[j], exprs2[j].Accept(foldingVisitor, Ig.nore)); //Assert.AreEqual(exprs[j], exprs2[j].Accept(foldingVisitor, 0)); } } }
private static void TestManyMinuses(IAbstractExpr a) { IAbstractExpr b = a; var foldingVisitor = new PolynomialFoldingVisitor(); for (int i = 0; i < 4; i++) { b = -(-b.C); Assert.AreEqual(a, b.Accept(foldingVisitor, Ig.nore)); } }