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);
}
}
}