using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics.Contracts; namespace AutoDiff { /// /// Base class for all automatically-differentiable terms. /// [Serializable] [ContractClass(typeof(TermContacts))] public abstract class Term { /// /// Accepts a term visitor /// /// The term visitor to accept public abstract void Accept(ITermVisitor visitor); /// /// Accepts a term visitor with a generic result /// /// The type of the result from the visitor's function /// The visitor to accept /// The result from the visitor's visit function. public abstract TResult Accept(ITermVisitor visitor); /// /// Converts a floating point constant to a constant term. /// /// The floating point constnat /// The resulting term. public static implicit operator Term(double value) { return TermBuilder.Constant(value); } /// /// Constructs a sum of the two given terms. /// /// First term in the sum /// Second term in the sum /// A term representing the sum of and . public static Term operator+(Term left, Term right) { if (left is Zero && right is Zero) return new Zero(); else if (left is Zero) return right; else if (right is Zero) return left; else return TermBuilder.Sum(left, right); } /// /// Constructs a product term of the two given terms. /// /// The first term in the product /// The second term in the product /// A term representing the product of and . public static Term operator*(Term left, Term right) { return TermBuilder.Product(left, right); } /// /// Constructs a fraction term of the two given terms. /// /// The numerator of the fraction. That is, the "top" part. /// The denominator of the fraction. That is, the "bottom" part. /// A term representing the fraction over . public static Term operator/(Term numerator, Term denominator) { return TermBuilder.Product(numerator, TermBuilder.Power(denominator, -1)); } /// /// Constructs a difference of the two given terms. /// /// The first term in the difference /// The second term in the difference. /// A term representing - . public static Term operator-(Term left, Term right) { return left + (-1) * right; } /// /// Constructs a negated term /// /// The term to negate /// A term representing -term. public static Term operator-(Term term) { return (-1) * term; } } [ContractClassFor(typeof(Term))] abstract class TermContacts : Term { public override void Accept(ITermVisitor visitor) { Contract.Requires(visitor != null); } public override TResult Accept(ITermVisitor visitor) { Contract.Requires(visitor != null); return default(TResult); } } }