namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions { using System; using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes; using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter; using HeuristicLab.Problems.ProgramSynthesis.Push.Stack; /// /// Pushes the sum of the top two items. /// [PushExpression(StackType.Float, "FLOAT.+")] public class FloatAddExpression : PushResultExpression { public override void Eval(IPushGpInterpreter interpreter) { Eval(interpreter.FloatStack, 2, values => values[0] + values[1]); } } /// /// Pushes the difference of the top two items; that is, the second item minus the top item. /// [PushExpression(StackType.Float, "FLOAT.-")] public class FloatSubtractExpression : PushResultExpression { public override void Eval(IPushGpInterpreter interpreter) { this.Eval(interpreter.FloatStack, 2, values => values[0] - values[1]); } } /// /// Pushes the product of the top two items. /// [PushExpression(StackType.Float, "FLOAT.*")] public class FloatMultiplyExpression : PushResultExpression { public override void Eval(IPushGpInterpreter interpreter) { this.Eval(interpreter.FloatStack, 2, values => values[0] * values[1]); } } /// /// Pushes the quotient of the top two items; that is, the second item divided by the top item. /// If the top item is zero this acts as a NOOP. /// [PushExpression(StackType.Float, "FLOAT./")] public class FloatDivideExpression : PushResultExpression { public override void Eval(IPushGpInterpreter interpreter) { this.Eval(interpreter.FloatStack, 2, values => values[0] / values[1], 0); } } /// /// Pushes the second stack item modulo the top stack item. If the top item is zero this acts as a NOOP. /// The modulus is computed as the remainder of the quotient, where the quotient has first been truncated toward /// negative infinity. /// (This is taken from the definition for the generic MOD function in Common Lisp, which is described /// for example at http://www.lispworks.com/reference/HyperSpec/Body/f_mod_r.htm.) /// [PushExpression(StackType.Float, "FLOAT.%")] public class FloatModuloExpression : PushResultExpression { public override void Eval(IPushGpInterpreter interpreter) { this.Eval(interpreter.FloatStack, 2, values => values[0] % values[1], 0); } } /// /// Pushes the minimum of the top two items. /// [PushExpression(StackType.Float, "FLOAT.MIN")] public class FloatMinExpression : PushResultExpression { public override void Eval(IPushGpInterpreter interpreter) { this.Eval(interpreter.FloatStack, 2, values => Math.Min(values[0], values[1])); } } /// /// Pushes the maximum of the top two items. /// [PushExpression(StackType.Float, "FLOAT.MAX")] public class FloatMaxExpression : PushResultExpression { public override void Eval(IPushGpInterpreter interpreter) { this.Eval(interpreter.FloatStack, 2, values => Math.Max(values[0], values[1])); } } /// /// Pushes TRUE onto the BOOLEAN stack if the second item is less than the top item, or FALSE otherwise. /// [PushExpression(StackType.Float, "FLOAT.<")] public class FloatSmallerThanExpression : PushResultExpression { public override void Eval(IPushGpInterpreter interpreter) { this.Eval(interpreter.FloatStack, interpreter.BooleanStack, 2, values => values[0] < values[1]); } } /// /// Pushes TRUE onto the BOOLEAN stack if the second item is greater than the top item, or FALSE otherwise. /// [PushExpression(StackType.Float, "FLOAT.>")] public class FloatGreaterThanExpression : PushResultExpression { public override void Eval(IPushGpInterpreter interpreter) { this.Eval(interpreter.FloatStack, interpreter.BooleanStack, 2, values => values[0] > values[1]); } } /// /// Pushes the sine of the top item. /// [PushExpression(StackType.Float, "FLOAT.SIN")] public class FloatSineExpression : PushResultExpression { public override void Eval(IPushGpInterpreter interpreter) { this.Eval(interpreter.FloatStack, 1, values => Math.Sin(values[0])); } } /// /// Pushes the cosine of the top item. /// [PushExpression(StackType.Float, "FLOAT.COS")] public class FloatCosineExpression : PushResultExpression { public override void Eval(IPushGpInterpreter interpreter) { this.Eval(interpreter.FloatStack, 1, values => Math.Cos(values[0])); } } /// /// Pushes 1 if the top BOOLEAN is TRUE, or 0 if the top BOOLEAN is FALSE. /// [PushExpression(StackType.Float, "FLOAT.FROMBOOLEAN")] public class FloatFromBooleanExpression : StatelessExpression { public override void Eval(IPushGpInterpreter interpreter) { if (interpreter.BooleanStack.Count == 0) return; var condition = interpreter.BooleanStack.Pop(); var value = condition ? 1 : 0; interpreter.FloatStack.Push(value); } } /// /// Pushes a floating point version of the top INTEGER. /// [PushExpression(StackType.Float, "FLOAT.FROMINTEGER")] public class FloatFromIntegerExpression : StatelessExpression { public override void Eval(IPushGpInterpreter interpreter) { if (interpreter.IntegerStack.Count == 0) return; var value = (double)interpreter.IntegerStack.Pop(); interpreter.FloatStack.Push(value); } } }