public void KeyPointingAtDependency()
        {
            var arith  = new MyBasicArithmetic();
            var system = new DependencySystem()
                         .Register <INumberInputs>()
                         .Register <IBasicArithmetic>(() => arith);

            system.Get <INumberInputs>().SetVariable("a", 1);
            system.Get <INumberInputs>().SetVariable("b", 2);
            system.Get <INumberInputs>().SetVariable("c", 3);

            Assert.AreEqual(1, system.Get <IBasicArithmetic>().V4("a", 0));
            Assert.AreEqual(3, system.Get <IBasicArithmetic>().V4("a", 2));
            Assert.AreEqual(7, system.Get <IBasicArithmetic>().V4("b", 5));
            Assert.AreEqual(9, system.Get <IBasicArithmetic>().V4("b", 7));
            Assert.AreEqual(8, system.Get <IBasicArithmetic>().V4("c", 5));

            system.Get <INumberInputs>().SetVariable("b", 1);

            Assert.AreEqual(1, system.Get <IBasicArithmetic>().V4("a", 0));
            Assert.AreEqual(3, system.Get <IBasicArithmetic>().V4("a", 2));
            Assert.AreEqual(6, system.Get <IBasicArithmetic>().V4("b", 5));
            Assert.AreEqual(8, system.Get <IBasicArithmetic>().V4("b", 7));
            Assert.AreEqual(8, system.Get <IBasicArithmetic>().V4("c", 5));
        }
        public void FlipBandCEarlyTerminatesV3()
        {
            var arith  = new MyBasicArithmetic();
            var system = new DependencySystem()
                         .Register <INumberInputs>()
                         .Register <IBasicArithmetic>(() => arith);

            system.Get <INumberInputs>().SetVariable("a", 1);
            system.Get <INumberInputs>().SetVariable("b", 2);
            system.Get <INumberInputs>().SetVariable("c", 3);

            // Now force-eval everyone
            var _1 = system.Get <IBasicArithmetic>().V1;
            var _2 = system.Get <IBasicArithmetic>().V3(1);

            // Swap values of b and c
            system.Get <INumberInputs>().SetVariable("b", 3);
            system.Get <INumberInputs>().SetVariable("c", 2);

            // v1 and v2 should be computed twice, v3 shouldn't be re-computed
            Assert.AreEqual(4, system.Get <IBasicArithmetic>().V1);
            Assert.AreEqual(6, system.Get <IBasicArithmetic>().V3(1));
            Assert.AreEqual(2, arith.V1_invocations);
            Assert.AreEqual(2, arith.V2_invocations);
            Assert.AreEqual(1, arith.V3_invocations[1]);
            Assert.AreEqual(6, system.Get <IBasicArithmetic>().V2);
        }
        public void UpdateB()
        {
            var arith  = new MyBasicArithmetic();
            var system = new DependencySystem()
                         .Register <INumberInputs>()
                         .Register <IBasicArithmetic>(() => arith);

            system.Get <INumberInputs>().SetVariable("a", 1);
            system.Get <INumberInputs>().SetVariable("b", 2);
            system.Get <INumberInputs>().SetVariable("c", 3);

            // Now force-eval everyone
            var _1 = system.Get <IBasicArithmetic>().V1;
            var _2 = system.Get <IBasicArithmetic>().V3(1);

            // Update b
            system.Get <INumberInputs>().SetVariable("b", 3);

            // Everything should be computed twice
            Assert.AreEqual(4, system.Get <IBasicArithmetic>().V1);
            Assert.AreEqual(9, system.Get <IBasicArithmetic>().V3(1));
            Assert.AreEqual(2, arith.V1_invocations);
            Assert.AreEqual(2, arith.V2_invocations);
            Assert.AreEqual(2, arith.V3_invocations[1]);
            Assert.AreEqual(9, system.Get <IBasicArithmetic>().V2);
            Assert.AreEqual(2, arith.V2_invocations);
        }
        public void FullComputationOnce()
        {
            var arith  = new MyBasicArithmetic();
            var system = new DependencySystem()
                         .Register <INumberInputs>()
                         .Register <IBasicArithmetic>(() => arith);

            system.Get <INumberInputs>().SetVariable("a", 1);
            system.Get <INumberInputs>().SetVariable("b", 2);
            system.Get <INumberInputs>().SetVariable("c", 3);

            Assert.AreEqual(3, system.Get <IBasicArithmetic>().V1);
            Assert.AreEqual(6, system.Get <IBasicArithmetic>().V3(1));
            Assert.AreEqual(1, arith.V1_invocations);
            Assert.AreEqual(1, arith.V2_invocations);
            Assert.AreEqual(1, arith.V3_invocations[1]);
            Assert.AreEqual(6, system.Get <IBasicArithmetic>().V2);
            Assert.AreEqual(1, arith.V2_invocations);
        }
        public void DifferentKeysAreOrthogonal()
        {
            var arith  = new MyBasicArithmetic();
            var system = new DependencySystem()
                         .Register <INumberInputs>()
                         .Register <IBasicArithmetic>(() => arith);

            system.Get <INumberInputs>().SetVariable("a", 1);
            system.Get <INumberInputs>().SetVariable("b", 2);
            system.Get <INumberInputs>().SetVariable("c", 3);

            Assert.AreEqual(3, system.Get <IBasicArithmetic>().V1);
            Assert.AreEqual(6, system.Get <IBasicArithmetic>().V2);
            Assert.AreEqual(6, system.Get <IBasicArithmetic>().V3(1));
            Assert.AreEqual(12, system.Get <IBasicArithmetic>().V3(2));
            Assert.AreEqual(1, arith.V1_invocations);
            Assert.AreEqual(1, arith.V2_invocations);
            Assert.AreEqual(1, arith.V3_invocations[1]);
            Assert.AreEqual(1, arith.V3_invocations[2]);
        }