Пример #1
0
        public void SetInput(string inputName, int value)
        {
            this.ValidateEditor();
            if (string.IsNullOrEmpty(inputName))
            {
                throw new ArgumentNullException(nameof(inputName));
            }
            InputPinSocket pin = this.socket.Inputs.FirstOrDefault(i => i.Pin.Name == inputName);

            if (pin == null)
            {
                throw new CircuitException(Cause.UserError,
                                           string.Format(CultureInfo.InvariantCulture, "Input pin {0} not found on Logical Circuit {1}", inputName, this.logicalCircuitName)
                                           );
            }
            pin.Function.Value = value;
            if (pin.Function.Value != value)
            {
                throw new CircuitException(Cause.UserError,
                                           string.Format(CultureInfo.InvariantCulture, "Value {0} get truncated by pin {1}. Make sure value can fit to {2} bit(s) of the pin.", value, inputName, pin.Pin.BitWidth)
                                           );
            }
        }
            private void Build(Action <double> reportProgress, Func <bool> keepGoing, Predicate <TruthState> include, int maxCount)
            {
                this.Results     = new List <TruthState>();
                this.Oscillation = false;
                this.Trancated   = false;
                int inputCount  = this.Inputs.Count;
                int outputCount = this.Outputs.Count;

                if (0 < inputCount && 0 < outputCount)
                {
                    BigInteger end        = this.Start + this.Count;
                    BigInteger onePercent = this.Count / 100;
                    BigInteger count      = 0;
                    double     progress   = 0;

                    TruthState state = new TruthState(inputCount, outputCount);
                    for (BigInteger value = this.Start; value < end; value++)
                    {
                        if (maxCount <= this.Results.Count || !keepGoing())
                        {
                            this.Trancated = true;
                            break;
                        }
                        int bit = 0;
                        for (int i = this.Inputs.Count - 1; 0 <= i; i--)
                        {
                            InputPinSocket pin = this.Inputs[i];
                            int            v   = (int)((value >> bit) & int.MaxValue) & (pin.Pin.BitWidth < 32 ? (1 << pin.Pin.BitWidth) - 1 : ~0);
                            pin.Function.Value = v;
                            Tracer.Assert(pin.Function.Value == v, "Value get truncated");
                            bit += pin.Pin.BitWidth;
                        }
                        if (!this.CircuitState.Evaluate(true))
                        {
                            this.Oscillation = true;
                            break;
                        }
                        for (int i = 0; i < inputCount; i++)
                        {
                            state.Input[i] = this.Inputs[i].Function.Value;
                        }
                        for (int i = 0; i < outputCount; i++)
                        {
                            state.Result[i] = this.Outputs[i].Function.Pack();
                        }
                        if (!state.Unpack(this.Outputs.Select(o => o.Function.ParameterCount).ToArray()) || include == null || include(state))
                        {
                            this.Results.Add(state);
                            state = new TruthState(inputCount, outputCount);
                        }
                        if (reportProgress != null)
                        {
                            count++;
                            if (onePercent < count)
                            {
                                count = 0;
                                if (onePercent == BigInteger.Zero)
                                {
                                    Tracer.Assert(0 < this.Count && this.Count < 100);
                                    reportProgress((double)((value + 1 - this.Start) * 100) / (double)this.Count);
                                }
                                else
                                {
                                    reportProgress(Math.Min(++progress, 100));
                                }
                            }
                        }
                    }
                }
            }