public void ReplaceBranchManipulationDistributionsTest() {
   SymbolicExpressionTreeStringFormatter formatter = new SymbolicExpressionTreeStringFormatter();
   var trees = new List<ISymbolicExpressionTree>();
   var grammar = Grammars.CreateArithmeticAndAdfGrammar();
   var random = new MersenneTwister(31415);
   for (int i = 0; i < POPULATION_SIZE; i++) {
     var tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
     SubroutineCreater.CreateSubroutine(random, tree, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
     string originalTree = formatter.Format(tree);
     ReplaceBranchManipulation.ReplaceRandomBranch(random, tree, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
     string manipulatedTree = formatter.Format(tree);
     Assert.IsFalse(originalTree == manipulatedTree);
     Util.IsValid(tree);
     trees.Add(tree);
   }
   Console.WriteLine("ReplaceBranchManipulation: " + Environment.NewLine +
     Util.GetSizeDistributionString(trees, 105, 5) + Environment.NewLine +
     Util.GetFunctionDistributionString(trees) + Environment.NewLine +
     Util.GetNumberOfSubtreesDistributionString(trees) + Environment.NewLine +
     Util.GetTerminalDistributionString(trees) + Environment.NewLine
     );
 }
 public void ChangeNodeTypeManipulationDistributionsTest() {
   SymbolicExpressionTreeStringFormatter formatter = new SymbolicExpressionTreeStringFormatter();
   var trees = new List<ISymbolicExpressionTree>();
   var grammar = Grammars.CreateArithmeticAndAdfGrammar();
   var random = new MersenneTwister(31415);
   int failedEvents = 0;
   for (int i = 0; i < POPULATION_SIZE; i++) {
     var tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
     string originalTree = formatter.Format(tree);
     ChangeNodeTypeManipulation.ChangeNodeType(random, tree);
     string manipulatedTree = formatter.Format(tree);
     if (originalTree == manipulatedTree) failedEvents++;
     Util.IsValid(tree);
     trees.Add(tree);
   }
   Console.WriteLine("ChangeNodeTypeManipulation: " + Environment.NewLine +
     "Failed events: " + failedEvents * 100.0 / POPULATION_SIZE + " %" + Environment.NewLine +
     Util.GetSizeDistributionString(trees, 105, 5) + Environment.NewLine +
     Util.GetFunctionDistributionString(trees) + Environment.NewLine +
     Util.GetNumberOfSubtreesDistributionString(trees) + Environment.NewLine +
     Util.GetTerminalDistributionString(trees) + Environment.NewLine
     );
   Assert.IsTrue(failedEvents * 100.0 / POPULATION_SIZE < 5.0); // only max 5% failed mutations are allowed
 }
 protected SymbolicExpressionTreeStringFormatter(SymbolicExpressionTreeStringFormatter original, Cloner cloner)
   : base(original, cloner) {
   Indent = original.Indent;
 }
 protected SymbolicExpressionTreeStringFormatter(SymbolicExpressionTreeStringFormatter original, Cloner cloner)
     : base(original, cloner)
 {
     Indent = original.Indent;
 }
 public void SimplifierAxiomsTest() {
   SymbolicExpressionImporter importer = new SymbolicExpressionImporter();
   SymbolicDataAnalysisExpressionTreeSimplifier simplifier = new SymbolicDataAnalysisExpressionTreeSimplifier();
   SymbolicExpressionTreeStringFormatter formatter = new SymbolicExpressionTreeStringFormatter();
   #region single argument arithmetics
   {
     var actualTree = simplifier.Simplify(importer.Import("(+ 1.0)"));
     var expectedTree = importer.Import("1.0");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     var actualTree = simplifier.Simplify(importer.Import("(+ (variable 2.0 a))"));
     var expectedTree = importer.Import("(variable 2.0 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     var actualTree = simplifier.Simplify(importer.Import("(- 1.0)"));
     var expectedTree = importer.Import("-1.0");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     var actualTree = simplifier.Simplify(importer.Import("(- (variable 2.0 a))"));
     var expectedTree = importer.Import("(variable -2.0 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     var actualTree = simplifier.Simplify(importer.Import("(* 2.0)"));
     var expectedTree = importer.Import("2.0");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     var actualTree = simplifier.Simplify(importer.Import("(* (variable 2.0 a))"));
     var expectedTree = importer.Import("(variable 2.0 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     var actualTree = simplifier.Simplify(importer.Import("(/ 2.0)"));
     var expectedTree = importer.Import("0.5");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     var actualTree = simplifier.Simplify(importer.Import("(/ (variable 2.0 a))"));
     var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   #endregion
   #region aggregation of constants into factors
   {
     var actualTree = simplifier.Simplify(importer.Import("(* 2.0 (variable 2.0 a))"));
     var expectedTree = importer.Import("(variable 4.0 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     var actualTree = simplifier.Simplify(importer.Import("(/ (variable 2.0 a) 2.0)"));
     var expectedTree = importer.Import("(variable 1.0 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     var actualTree = simplifier.Simplify(importer.Import("(/ (variable 2.0 a) (* 2.0 2.0))"));
     var expectedTree = importer.Import("(variable 0.5 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   #endregion
   #region constant and variable folding
   {
     var actualTree = simplifier.Simplify(importer.Import("(+ 1.0 2.0)"));
     var expectedTree = importer.Import("3.0");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     var actualTree = simplifier.Simplify(importer.Import("(+ (variable 2.0 a) (variable 2.0 a))"));
     var expectedTree = importer.Import("(variable 4.0 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     var actualTree = simplifier.Simplify(importer.Import("(- (variable 2.0 a) (variable 1.0 a))"));
     var expectedTree = importer.Import("(variable 1.0 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     var actualTree = simplifier.Simplify(importer.Import("(* (variable 2.0 a) (variable 2.0 a))"));
     var expectedTree = importer.Import("(* (* (variable 1.0 a) (variable 1.0 a)) 4.0)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     var actualTree = simplifier.Simplify(importer.Import("(/ (variable 1.0 a) (variable 2.0 a))"));
     var expectedTree = importer.Import("0.5");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   #endregion
   #region logarithm rules
   {
     // cancellation
     var actualTree = simplifier.Simplify(importer.Import("(log (exp (variable 2.0 a)))"));
     var expectedTree = importer.Import("(variable 2.0 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // must not transform logs in this way as we do not know wether both variables are positive
     var actualTree = simplifier.Simplify(importer.Import("(log (* (variable 1.0 a) (variable 1.0 b)))"));
     var expectedTree = importer.Import("(log (* (variable 1.0 a) (variable 1.0 b)))");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // must not transform logs in this way as we do not know wether both variables are positive
     var actualTree = simplifier.Simplify(importer.Import("(log (/ (variable 1.0 a) (variable 1.0 b)))"));
     var expectedTree = importer.Import("(log (/ (variable 1.0 a) (variable 1.0 b)))");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   #endregion
   #region exponentiation rules
   {
     // cancellation
     var actualTree = simplifier.Simplify(importer.Import("(exp (log (variable 2.0 a)))"));
     var expectedTree = importer.Import("(variable 2.0 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // exp transformation
     var actualTree = simplifier.Simplify(importer.Import("(exp (+ (variable 2.0 a) (variable 3.0 b)))"));
     var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (variable 3.0 b)))");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // exp transformation
     var actualTree = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (variable 3.0 b)))"));
     var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (variable -3.0 b)))");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // exp transformation
     var actualTree = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (* (variable 3.0 b) (variable 4.0 c))))"));
     var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (variable 1.0 c) -12.0)))");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // exp transformation
     var actualTree = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (* (variable 3.0 b) (cos (variable 4.0 c)))))"));
     var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (cos (variable 4.0 c)) -3.0)))");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   #endregion
   #region power rules
   {
     // cancellation
     var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) 0.0)"));
     var expectedTree = importer.Import("1.0");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // fixed point
     var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) 1.0)"));
     var expectedTree = importer.Import("(variable 2.0 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // inversion fixed point
     var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) -1.0)"));
     var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // inversion 
     var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) -2.0)"));
     var expectedTree = importer.Import("(/ 1.0 (pow (variable 2.0 a) 2.0))");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // constant folding
     var actualTree = simplifier.Simplify(importer.Import("(pow 3.0 2.0)"));
     var expectedTree = importer.Import("9.0");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   #endregion
   #region root rules
   {
     // cancellation
     var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) 0.0)"));
     var expectedTree = importer.Import("1.0");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // fixed point
     var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) 1.0)"));
     var expectedTree = importer.Import("(variable 2.0 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // inversion fixed point
     var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) -1.0)"));
     var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // inversion
     var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) -2.0)"));
     var expectedTree = importer.Import("(/ 1.0 (root (variable 2.0 a) 2.0))");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // constant folding
     var actualTree = simplifier.Simplify(importer.Import("(root 9.0 2.0)"));
     var expectedTree = importer.Import("3.0");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   #endregion
   #region boolean operations
   {
     // always true and
     var actualTree = simplifier.Simplify(importer.Import("(and 1.0 2.0)"));
     var expectedTree = importer.Import("1.0");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // always false and
     var actualTree = simplifier.Simplify(importer.Import("(and 1.0 -2.0)"));
     var expectedTree = importer.Import("-1.0");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // always true or
     var actualTree = simplifier.Simplify(importer.Import("(or -1.0 2.0)"));
     var expectedTree = importer.Import("1.0");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // always false or
     var actualTree = simplifier.Simplify(importer.Import("(or -1.0 -2.0)"));
     var expectedTree = importer.Import("-1.0");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // constant not 
     var actualTree = simplifier.Simplify(importer.Import("(not -2.0)"));
     var expectedTree = importer.Import("1.0");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // constant not 
     var actualTree = simplifier.Simplify(importer.Import("(not 2.0)"));
     var expectedTree = importer.Import("-1.0");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // constant not 
     var actualTree = simplifier.Simplify(importer.Import("(not 0.0)"));
     var expectedTree = importer.Import("1.0");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // nested nots
     var actualTree = simplifier.Simplify(importer.Import("(not (not 1.0))"));
     var expectedTree = importer.Import("1.0");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // not of non-Boolean argument
     var actualTree = simplifier.Simplify(importer.Import("(not (variable 1.0 a))"));
     var expectedTree = importer.Import("(not (> (variable 1.0 a) 0.0))");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // not Boolean argument
     var actualTree = simplifier.Simplify(importer.Import("(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))"));
     var expectedTree = importer.Import("(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   #endregion
   #region conditionals
   {
     // always false
     var actualTree = simplifier.Simplify(importer.Import("(if -1.0 (variable 2.0 a) (variable 3.0 a))"));
     var expectedTree = importer.Import("(variable 3.0 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // always true
     var actualTree = simplifier.Simplify(importer.Import("(if 1.0 (variable 2.0 a) (variable 3.0 a))"));
     var expectedTree = importer.Import("(variable 2.0 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // always false (0.0)
     var actualTree = simplifier.Simplify(importer.Import("(if 0.0 (variable 2.0 a) (variable 3.0 a))"));
     var expectedTree = importer.Import("(variable 3.0 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // complex constant condition (always false)
     var actualTree = simplifier.Simplify(importer.Import("(if (* 1.0 -2.0) (variable 2.0 a) (variable 3.0 a))"));
     var expectedTree = importer.Import("(variable 3.0 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // complex constant condition (always false)
     var actualTree = simplifier.Simplify(importer.Import("(if (/ (variable 1.0 a) (variable -2.0 a)) (variable 2.0 a) (variable 3.0 a))"));
     var expectedTree = importer.Import("(variable 3.0 a)");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   {
     // insertion of relational operator
     var actualTree = simplifier.Simplify(importer.Import("(if (variable 1.0 a) (variable 2.0 a) (variable 3.0 a))"));
     var expectedTree = importer.Import("(if (> (variable 1.0 a) 0.0) (variable 2.0 a) (variable 3.0 a))");
     Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
   }
   #endregion
 }