public static ITheorem[] BuildTheorems(Context context)
        {
            ITheorem[] theorems = new ITheorem[2];

            theorems[0] = new Analysis.DerivativeTransformation(context.Library.LookupEntity(_entityId),
                delegate(Port port, SignalSet manipulatedInputs, Signal variable, bool hasManipulatedInputs)
                {
                    Builder b = context.Builder;
                    Signal[] outputs = new Signal[manipulatedInputs.Count];
                    ReadOnlySignalSet squares = b.Square(port.OutputSignals);
                    Signal one = IntegerValue.ConstantOne(context);
                    for(int i = 0; i < outputs.Length; i++)
                        outputs[i] = (one + squares[i]) * manipulatedInputs[i];
                    return b.Negate(outputs);
                });

            theorems[1] = new BasicTransformation("CotangentTrigonometricSusbtitute", "Std", "TrigonometricSubstitute", "Std",
                delegate(Port port) { return port.Entity.EntityId.Equals("Cotangent", "Std"); },
                delegate(Port port) { return ManipulationPlan.DoAlter; },
                delegate(Port port, SignalSet transformedInputs, bool hasTransformedInputs)
                {
                    Signal[] ret = new Signal[transformedInputs.Count];
                    for(int i = 0; i < ret.Length; i++)
                        ret[i] = Std.Cosine(port.Context, transformedInputs[i]) / Std.Sine(port.Context, transformedInputs[i]);
                    return ret;
                });

            return theorems;
        }
        public static ITheorem[] BuildTheorems(Context context)
        {
            ITheorem[] theorems = new ITheorem[2];

            theorems[0] = new Analysis.DerivativeTransformation(context.Library.LookupEntity(_entityId),
                delegate(Port port, SignalSet manipulatedInputs, Signal variable, bool hasManipulatedInputs)
                {
                    Builder b = context.Builder;
                    Signal[] outputs = new Signal[manipulatedInputs.Count];
                    ReadOnlySignalSet cotangents = Std.Cotangent(context, port.InputSignals);
                    for(int i = 0; i < outputs.Length; i++)
                        outputs[i] = b.MultiplySimplified(port.OutputSignals[i], cotangents[i], manipulatedInputs[i]);
                    return b.Negate(outputs);
                });

            theorems[1] = new BasicTransformation("CosecantTrigonometricSusbtitute", "Std", "TrigonometricSubstitute", "Std",
                delegate(Port port) { return port.Entity.EntityId.Equals("Cosecant", "Std"); },
                delegate(Port port) { return ManipulationPlan.DoAlter; },
                delegate(Port port, SignalSet transformedInputs, bool hasTransformedInputs)
                {
                    return port.Context.Builder.Invert(Std.Sine(port.Context, transformedInputs));
                    //Signal[] ret = new Signal[transformedInputs.Count];
                    //for(int i = 0; i < ret.Length; i++)
                    //    ret[i] = port.Context.Builder.Invert(Std.Sine(port.Context, transformedInputs[i]));
                    //return ret;
                });

            return theorems;
        }
        public static ITheorem[] BuildTheorems(Context context)
        {
            ITheorem[] theorems = new ITheorem[2];

            theorems[0] = new Analysis.DerivativeTransformation(_entityId,
                delegate(Port port, SignalSet manipulatedInputs, Signal variable, bool hasManipulatedInputs)
                {
                    Builder b = context.Builder;
                    ReadOnlySignalSet squares = b.Square(port.OutputSignals);
                    Signal one = IntegerValue.ConstantOne(context);
                    SignalSet outputs = new SignalSet();
                    for(int i = 0; i < manipulatedInputs.Count; i++)
                        outputs.Add((one + squares[i]) * manipulatedInputs[i]);
                    return outputs;
                });

            theorems[1] = new BasicTransformation(_entityId.DerivePostfix("TrigonometricSubstitute"), new MathIdentifier("TrigonometricSubstitute", "Std"),
                delegate() { return new Pattern(new EntityCondition(_entityId)); },
                delegate(Port port) { return ManipulationPlan.DoAlter; },
                delegate(Port port, SignalSet transformedInputs, bool hasTransformedInputs)
                {
                    Signal[] ret = new Signal[transformedInputs.Count];
                    for(int i = 0; i < ret.Length; i++)
                        ret[i] = Std.Sine(port.Context, transformedInputs[i]) / Std.Cosine(port.Context, transformedInputs[i]);
                    return ret;
                });

            return theorems;
        }
        public static ITheorem[] BuildTheorems(Context context)
        {
            ITheorem[] theorems = new ITheorem[2];

            theorems[0] = new Analysis.DerivativeTransformation(_entityId,
                delegate(Port port, SignalSet manipulatedInputs, Signal variable, bool hasManipulatedInputs)
                {
                    Builder b = context.Builder;
                    ReadOnlySignalSet tangents = Std.Tangent(context, port.InputSignals);
                    SignalSet outputs = new SignalSet();
                    for(int i = 0; i < manipulatedInputs.Count; i++)
                        outputs.Add(b.MultiplySimplified(port.OutputSignals[i], tangents[i], manipulatedInputs[i]));
                    return outputs;
                });

            theorems[1] = new BasicTransformation(_entityId.DerivePostfix("TrigonometricSubstitute"), new MathIdentifier("TrigonometricSubstitute", "Std"),
                delegate() { return new Pattern(new EntityCondition(_entityId)); },
                delegate(Port port) { return ManipulationPlan.DoAlter; },
                delegate(Port port, SignalSet transformedInputs, bool hasTransformedInputs)
                {
                    return port.Context.Builder.Invert(Std.Cosine(port.Context, transformedInputs));
                    //Signal[] ret = new Signal[transformedInputs.Length];
                    //for(int i = 0; i < ret.Length; i++)
                    //    ret[i] = port.Context.Builder.Invert(Std.Cosine(port.Context, transformedInputs[i]));
                    //return ret;
                });

            return theorems;
        }