using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace VSpace { using V = VectorSpace<double, DoubleField, bool>; interface IField<T> { T Add(T a, T b); T Sub(T a, T b); T Mul(T a, T b); T Div(T a, T b); T FromIntegral(int a); } struct DoubleField : IField<double> { public double Add(double a, double b) { return a + b; } public double Sub(double a, double b) { return a - b; } public double Mul(double a, double b) { return a * b; } public double Div(double a, double b) { return a / b; } public double FromIntegral(int a) { return a; } } class VectorSpace<K, F, A> where F : IField<K>, new() { private IField<K> field = new F(); private Dictionary<A, K> items = new Dictionary<A,K>(); private VectorSpace() {} private static VectorSpace<K, F, A> z = new VectorSpace<K, F, A>(); public static VectorSpace<K, F, A> Zero { get { return z;} } public VectorSpace(A x) { items[x] = field.FromIntegral(1); } public static VectorSpace<K,F,A> Unit(A obj) { return new VectorSpace<K, F, A>(obj); } public K this[A key] { get { return this.items.ContainsKey(key) ? this.items[key] : field.FromIntegral(0); } private set { this.items[key] = value; } } public static VectorSpace<K, F, A> operator +(VectorSpace<K, F, A> v1, VectorSpace<K, F, A> v2) { var res = new VectorSpace<K, F, A>(); var field = v1.field; foreach (var kv in v1.items.Union(v2.items)) { var k = kv.Key; res[k] = field.Add(v1[k],v2[k]); } return res; } public static VectorSpace<K, F, A> operator *(K scalar, VectorSpace<K, F, A> v) { var res = new VectorSpace<K, F, A>(); var field = v.field; foreach (var kv in v.items) { res[kv.Key] = field.Mul(scalar, kv.Value); } return res; } public static VectorSpace<K, F, A> operator -(VectorSpace<K, F, A> v1, VectorSpace<K, F, A> v2) { var field = v1.field; return v1 + (field.FromIntegral(-1) * v2); } public struct ScalarObjectPair { private K s; private A o; public K Scalar { get { return s; } set { s = value; } } public A Object { get { return o; } set { o = value; } } } public IEnumerator<ScalarObjectPair> GetEnumerator() { foreach (var kv in this.items) yield return new ScalarObjectPair { Scalar = kv.Value, Object = kv.Key }; } public override String ToString() { return "V<" + String.Join( ", ", (from kv in this.items let k = kv.Key.ToString() let v = kv.Value.ToString() select v + ":" + k).ToArray() ) + ">"; } } static class VectorSpaceLINQ { public static VectorSpace<K, F, B> Select<K, F, A, B>(this VectorSpace<K, F, A> v, Func<A, B> f) where F : IField<K>, new() { var res = VectorSpace<K, F, B>.Zero; foreach (var x in v) { res += x.Scalar * new VectorSpace<K, F, B>(f(x.Object)); } return res; } public static VectorSpace<K, F, A> Join<K, F, A>(this VectorSpace<K, F, VectorSpace<K, F, A>> v) where F : IField<K>, new() { var res = VectorSpace<K, F, A>.Zero; foreach (var x in v) { res += (x.Scalar * x.Object); } return res; } public static VectorSpace<K, F, B> SelectMany<K, F, A, B>( this VectorSpace<K, F, A> v, Func<A, VectorSpace<K, F, B>> f ) where F : IField<K>, new() { return v.Select(f).Join(); } public static VectorSpace<K, F, C> SelectMany<K, F, A, B, C>( this VectorSpace<K, F, A> v, Func<A, VectorSpace<K, F, B>> f, Func<A,B,C> g ) where F : IField<K>, new() { return v.SelectMany(a => f(a).Select(b => g(a, b))); } public static VectorSpace<K, F, A> Where<K, F, A>(this VectorSpace<K, F, A> v, Func<A, bool> p) where F : IField<K>, new() { return v.SelectMany(a => p(a) ? VectorSpace<K, F, A>.Unit(a) : VectorSpace<K, F, A>.Zero); } } class Program { static V VFalse = new V(false); static V VTrue = new V(true); static V Rain() { return 0.2 * VTrue + 0.8 * VFalse; } static V Sprinkler(bool raining) { return raining ? (0.01 * VTrue + 0.99 * VFalse) : (0.4 * VTrue + 0.6 * VFalse); } static V Grass(bool sprinkler, bool raining) { return sprinkler ? ( raining ? (0.99 * VTrue + 0.01 * VFalse) : (0.9 * VTrue + 0.1 * VFalse) ) : ( raining ? (0.8 * VTrue + 0.2 * VFalse) : VFalse ); } static void Main(string[] args) { var grasswet = from r in Rain() from s in Sprinkler(r) from g in Grass(s, r) select g; var diditrain = from r in Rain() from s in Sprinkler(r) from g in Grass(s, r) where g select r; Console.WriteLine(grasswet); // V<0,44838:True, 0,55162:False> Console.WriteLine(diditrain); // V<0,16038:True, 0,288:False> Console.ReadKey(); } } }