Пример #1
0
 public static SchemeState StepBack(SchemeState state)
 {
     // todo:
     // - declare StepBack in value generators
     // - ???
     throw new NotImplementedException();
 }
Пример #2
0
        private static SchemeState Step(SchemeState state, bool dry)
        {
            var gateStates      = state.Gates.ToDictionary(x => x.Key, x => x.Value); // duplicating gate states
            var nodeStates      = state.Nodes.ToDictionary(x => x.Key, x => new NodeState(x.Key, false));
            var inputPinStates  = new Dictionary <Pin, PinState>();
            var outputPinStates = new Dictionary <Pin, PinState>();

            bool Nor(IEnumerable <SchemeNode> nodes) => nodes.Aggregate(true, (b, node) => b && !nodeStates[node].IsHigh);
            bool Or(IEnumerable <SchemeNode> nodes) => nodes.Aggregate(false, (b, node) => b || nodeStates[node].IsHigh);

            void UpdateGateState(KeyValuePair <SchemeGate, GateState> gateInfo)
            {
                var gate = gateInfo.Key;

                gateStates[gate] = new GateState(gate, gate.IsInversionGate
                    ? gate.GateInputs.Aggregate(true, (old, pair) => old && Nor(pair))
                    : gate.GateInputs.Aggregate(true, (old, pair) => old && Or(pair)));
            }

            void UpdatePinValues()
            {
                foreach (var(pin, pinState) in state.InputPinStates.Concat(state.OutputPinStates))
                {
                    var(isHigh, newState) = dry ? (false, pinState.GeneratorState) : pin.ValuesFunction.Step(pinState.GeneratorState);

                    if (pin.IsOutputPin)
                    {
                        outputPinStates[pin] = new PinState(pin, isHigh, newState);
                    }
                    else
                    {
                        inputPinStates[pin] = new PinState(pin, isHigh, newState);
                    }
                }
            }

            void LoadPinNodes()
            {
                foreach (var(n, _) in state.Nodes)
                {
                    foreach (var p in n.Pins)
                    {
                        if (inputPinStates.TryGetValue(p, out var pinState) && pinState.IsHigh)
                        {
                            nodeStates[n] = new NodeState(n, true);
                        }
                    }
                }
            }

            void PropagateHigh()
            {
                for (bool hadChanges = true; hadChanges; hadChanges = false)
                {
                    foreach (var(gate, gateState) in gateStates)
                    {
                        if (gateState.IsOpen)
                        {
                            var left   = nodeStates[gate.GatePowerNodes[0]];
                            var right  = nodeStates[gate.GatePowerNodes[1]];
                            var isHigh = left.IsHigh || right.IsHigh;
                            hadChanges |= left.IsHigh != right.IsHigh;
                            nodeStates[gate.GatePowerNodes[0]] = new NodeState(gate.GatePowerNodes[0], isHigh);
                            nodeStates[gate.GatePowerNodes[1]] = new NodeState(gate.GatePowerNodes[1], isHigh);
                        }
                    }
                }
            }

            void CalculateGates()
            {
                state.Gates.ForEach(UpdateGateState);
            }

            UpdatePinValues();
            LoadPinNodes();
            PropagateHigh();
            CalculateGates();

            return(new SchemeState(state.InputPins, state.OutputPins, state.PinNodes,
                                   gateStates, nodeStates, inputPinStates, outputPinStates,
                                   state.OutputPins.ToDictionary(pin => pin, pin => state.PinNodes[pin].Any(node => nodeStates[node].IsHigh))));
        }
Пример #3
0
 public static SchemeState Step(SchemeState state) => Step(state, false);
Пример #4
0
        public static SchemeState InitState(Topology.Topology topology)
        {
            var state = new SchemeState(topology);

            return(Step(state, true)); // ensuring gates in the right states
        }