public ElementValue[,] CalculateTable() { #if DEBUG Log.Method( new MethodInfo { Name = "Scheme::CalculateTable", Type = typeof(ElementValue[, ]) } ); #endif var inputs_count_pow2 = Convert.ToInt32(Math.Pow(2, _inputs.Count)); var inputs_plus_outputs_count = _inputs.Count + _outputs.Count; var table = new ElementValue[inputs_count_pow2, inputs_plus_outputs_count]; for (int i = 0; i < inputs_count_pow2; i++) { SetCurrentState(i); CalculateForCurrentState(); for (int j = 0; j < inputs_plus_outputs_count; j++) { if (j < _inputs.Count) { table[i, j] = _inputs[j].Value; } else { table[i, j] = _outputs[j - _inputs.Count].Value; } } } return(table); }
public void CalculateForCurrentState() { #if DEBUG Log.Method( new MethodInfo { Name = "Scheme::CalculateForCurrentState", Type = typeof(void) } ); #endif foreach (var layer in _componentLayers) { foreach (var component in layer) { var values = new ElementValue[component.Input.Count]; for (int i = 0; i < component.Input.Count; i++) { values[i] = GetElementValue(component.Input.ElementAt(i)); } component.Calculate(values); } } foreach (var output in _outputs) { output.Value = GetElementValue(output.Input); } }
public Component(string name, ComponentType type, IEnumerable <string> input) { #if DEBUG Log.Method( new MethodInfo { Name = "Component::ctor", Type = typeof(Component) }, new ArgumentInfo { Name = nameof(name), Type = name.GetType(), Data = name }, new ArgumentInfo { Name = nameof(type), Type = type.GetType(), Data = type }, new ArgumentInfo { Name = nameof(input), Type = input.GetType(), Data = input } ); #endif Name = name; Type = type; _input = input.ToList(); Value = new ElementValue(); }
public void SetCurrentState(int stateNumber) { #if DEBUG Log.Method( new MethodInfo { Name = "Scheme::SetCurrentState", Type = typeof(void) }, new ArgumentInfo { Name = nameof(stateNumber), Type = stateNumber.GetType(), Data = stateNumber } ); #endif #region arguments check if (stateNumber >= Convert.ToInt32(Math.Pow(2, _inputs.Count)) || stateNumber < 0) { throw new ArgumentOutOfRangeException( nameof(stateNumber), $"The state number must be greater than or equal to 0 and less than 2 in power of the count of the inputs ({Convert.ToInt32(Math.Pow(2, _inputs.Count))})." ); } #endregion var state = new ElementValue[_inputs.Count]; for (int i = 0; i < state.Length; i++) { state[state.Length - i - 1] = new ElementValue(); state[state.Length - i - 1].Value = ((stateNumber >> i) & 1) == 1; state[state.Length - i - 1].Delay = 0; } SetCurrentState(state); }
public void Calculate(ElementValue[] inputValues) { #if DEBUG Log.Method( new MethodInfo { Name = "Component::Calculate", Type = typeof(void) }, new ArgumentInfo { Name = nameof(inputValues), Type = inputValues.GetType(), Data = inputValues } ); #endif #region arguments check if (inputValues == null) { throw new ArgumentNullException(nameof(inputValues)); } #endregion ElementValue tmp = new ElementValue(); switch (Type) { case ComponentType.And: tmp.Value = true; foreach (var inputValue in inputValues) { tmp.Value = tmp.Value.Value && inputValue.Value.Value; } if (tmp.Value == true) { tmp.Delay = inputValues.Max(x => x.Delay) + 1; } else { tmp.Delay = inputValues.Where(x => x.Value == false).Min(y => y.Delay) + 1; } break; case ComponentType.AndNot: tmp.Value = true; foreach (var inputValue in inputValues) { tmp.Value = tmp.Value.Value && inputValue.Value.Value; } if (tmp.Value == true) { tmp.Delay = inputValues.Max(x => x.Delay) + 1; } else { tmp.Delay = inputValues.Where(x => x.Value == false).Min(y => y.Delay) + 1; } tmp.Value = !tmp.Value; break; case ComponentType.Or: tmp.Value = false; foreach (var inputValue in inputValues) { tmp.Value = tmp.Value.Value || inputValue.Value.Value; } if (tmp.Value == true) { tmp.Delay = inputValues.Where(x => x.Value == true).Min(x => x.Delay) + 1; } else { tmp.Delay = inputValues.Max(y => y.Delay) + 1; } break; case ComponentType.OrNot: tmp.Value = false; foreach (var inputValue in inputValues) { tmp.Value = tmp.Value.Value || inputValue.Value.Value; } if (tmp.Value == true) { tmp.Delay = inputValues.Where(x => x.Value == true).Min(x => x.Delay) + 1; } else { tmp.Delay = inputValues.Max(y => y.Delay) + 1; } tmp.Value = !tmp.Value; break; case ComponentType.Xor: tmp.Value = false; foreach (var inputValue in inputValues) { tmp.Value = tmp.Value.Value ^ inputValue.Value.Value; } tmp.Delay = inputValues.Max(y => y.Delay) + 1; break; case ComponentType.XorNot: tmp.Value = false; foreach (var inputValue in inputValues) { tmp.Value = tmp.Value.Value ^ inputValue.Value.Value; } tmp.Delay = inputValues.Max(y => y.Delay) + 1; tmp.Value = !tmp.Value; break; case ComponentType.Not: tmp.Value = !inputValues[0].Value.Value; tmp.Delay = inputValues[0].Delay + 1; break; default: break; } Value = tmp; }
public Bitmap DrawTimeDiagram(uint[,] InputDelays, uint TimeLimit) { #if DEBUG Log.Method( new MethodInfo { Name = "Scheme::DrawTimeDiagram", Type = typeof(Bitmap) }, new ArgumentInfo { Name = nameof(InputDelays), Type = InputDelays.GetType(), Data = InputDelays }, new ArgumentInfo { Name = nameof(TimeLimit), Type = InputDelays.GetType(), Data = TimeLimit } ); #endif var rows = _inputs.Select(x => x.Name).Concat(_outputs.Select(x => x.Name)).ToArray(); int ImgRows = _inputs.Count + _outputs.Count; int ImgStepColumns = (int)(TimeLimit); int ImgWidth = fieldFirstWidth + ImgStepColumns * fieldStepWidth; int ImgHeight = fieldHeight * ImgRows; var bt = new Bitmap(ImgWidth, ImgHeight); var gr = Graphics.FromImage(bt); gr.FillRectangle(Brushes.White, 0, 0, ImgWidth, ImgHeight); Pen gridPen = new Pen(Color.Black); gridPen.DashStyle = DashStyle.Solid; for (int gor = 1; gor <= ImgRows; gor++) { gr.DrawLine(gridPen, 0, gor * fieldHeight, ImgWidth, gor * fieldHeight); gr.DrawString(rows[gor - 1], new Font("Arial", 10), Brushes.Black, new RectangleF(5, gor * fieldHeight - 20, fieldFirstWidth, 20)); } gridPen.Width = 2; gr.DrawLine(gridPen, fieldFirstWidth, 0, fieldFirstWidth, ImgHeight); gridPen.Width = 1; gridPen.Color = Color.Gray; gridPen.DashStyle = DashStyle.Dot; for (int ver = 0; ver <= ImgStepColumns; ver++) { gr.DrawLine(gridPen, fieldFirstWidth + ver * fieldStepWidth, 0, fieldFirstWidth + ver * fieldStepWidth, ImgHeight); } gridPen.Color = Color.Red; gridPen.Width = 2; gridPen.DashStyle = DashStyle.Solid; uint[] LastInputChangeTick = new uint[_inputs.Count]; ElementValue[] state = new ElementValue[_inputs.Count]; for (int i = 0; i < _inputs.Count; i++) { state[i] = new ElementValue() { Delay = 0, Value = false } } ; bool[,] inputValues = new bool[_inputs.Count, TimeLimit]; ElementValue[,] outputValue = new ElementValue[_outputs.Count, TimeLimit]; for (uint CurrentTick = 0; CurrentTick < TimeLimit; CurrentTick++) { for (int i = 0; i < _inputs.Count; i++) { if (CurrentTick - LastInputChangeTick[i] >= InputDelays[i, state[i].Value.Value ? 1 : 0]) { LastInputChangeTick[i] = CurrentTick; state[i].Value = !state[i].Value; } inputValues[i, CurrentTick] = state[i].Value.Value; } SetCurrentState(state); CalculateForCurrentState(); for (int i = 0; i < _outputs.Count; i++) { outputValue[i, CurrentTick] = _outputs[i].Value; } } for (int rw = 0; rw < ImgRows; rw++) { List <Point> sigLv = new List <Point>(); if (rw < _inputs.Count) { sigLv.Add(new Point(fieldFirstWidth, (int)((rw + (inputValues[rw, 0] ? .3f : 1f)) * fieldHeight))); sigLv.Add(new Point(fieldFirstWidth + fieldStepWidth, (int)((rw + (inputValues[rw, 0] ? .3f : 1f)) * fieldHeight))); } else { sigLv.Add(new Point(fieldFirstWidth, (int)((rw + (outputValue[rw - _inputs.Count, 0].Value.Value ? .3f : 1f)) * fieldHeight))); sigLv.Add(new Point(fieldFirstWidth + fieldStepWidth, (int)((rw + (outputValue[rw - _inputs.Count, 0].Value.Value ? .3f : 1f)) * fieldHeight))); } for (int tick = 1; tick < TimeLimit; tick++) { if (rw < _inputs.Count) { sigLv.Add(new Point(fieldFirstWidth + tick * fieldStepWidth, (int)((rw + (inputValues[rw, tick] ? .3f : 1f)) * fieldHeight))); sigLv.Add(new Point(fieldFirstWidth + (tick + 1) * fieldStepWidth, (int)((rw + (inputValues[rw, tick] ? .3f : 1f)) * fieldHeight))); } else { if (outputValue[rw - _inputs.Count, tick - 1].Value.Value ^ outputValue[rw - _inputs.Count, tick].Value.Value) { int dx = (int)(fieldStepWidth * outputValue[rw - _inputs.Count, tick].Delay.Value / (_componentLayers.Count + 1)); sigLv.Add(new Point(fieldFirstWidth + tick * fieldStepWidth + dx, (int)((rw + (outputValue[rw - _inputs.Count, tick - 1].Value.Value ? .3f : 1f)) * fieldHeight))); // last sigLv.Add(new Point(dx + fieldFirstWidth + tick * fieldStepWidth, (int)((rw + (outputValue[rw - _inputs.Count, tick].Value.Value ? .3f : 1f)) * fieldHeight))); sigLv.Add(new Point(fieldFirstWidth + (tick + 1) * fieldStepWidth, (int)((rw + (outputValue[rw - _inputs.Count, tick].Value.Value ? .3f : 1f)) * fieldHeight))); } else { sigLv.Add(new Point(fieldFirstWidth + tick * fieldStepWidth, (int)((rw + (outputValue[rw - _inputs.Count, tick].Value.Value ? .3f : 1f)) * fieldHeight))); sigLv.Add(new Point(fieldFirstWidth + (tick + 1) * fieldStepWidth, (int)((rw + (outputValue[rw - _inputs.Count, tick].Value.Value ? .3f : 1f)) * fieldHeight))); } } } gr.DrawLines(gridPen, sigLv.ToArray()); } gr.Dispose(); return(bt); }