using System.Collections.Generic;
public static class Initialization
public const string RG1Name = "RG1";
public const string RG2Name = "RG2";
public const string Sum1Name = "Sum1";
public const string SumResName = "Sum res";
public const string Sum2Name = "Sum2";
public const string Sum3Name = "Sum3";
public const string yName = "y";
public const string xName = "x";
public const int xMax = 50;
public static class Constants
public const string RG1Name = Initialization.RG1Name;
public const string RG2Name = Initialization.RG2Name;
public const string Sum1Name = Initialization.Sum1Name;
public const string SumResName = Initialization.SumResName;
public const string Sum2Name = Initialization.Sum2Name;
public const string Sum3Name = Initialization.Sum3Name;
public const string yName = Initialization.yName;
public const string xName = Initialization.xName;
public const int xMax = Initialization.xMax;
MutableMemoryElement getMemoryElement();
public class MemoryElementWithStepActivation
public MemoryElementWithStepActivation(
MemoryElementWithStep _memoryElementWithStep
m_memoryElementWithStep = _memoryElementWithStep;
m_prevNumber = _prevNumber;
m_newNumber = _newNumber;
public MutableMemoryElement getMemoryElement()
return m_memoryElementWithStep;
public int getPrevNumber()
public int getNumberToAdd()
public int getNewNumber()
public MemoryElementWithStep m_memoryElementWithStep;
public class AndGateActivation
public AndGateActivation(
MutableMemoryElement _mutableElement
m_mutableElement = _mutableElement;
m_prevNumber = _prevNumber;
m_numberToAdd = _numberToAdd;
m_newNumber = _newNumber;
public MutableMemoryElement getMemoryElement()
public int getPrevNumber()
public int getNumberToAdd()
public int getNewNumber()
public MutableMemoryElement m_mutableElement;
public int m_numberToAdd;
m_events = new List< IEvent >();
public void addEvent( IEvent _event )
foreach ( IEvent currentEvent in m_events )
MemoryElementWithStepActivation memoryElementWithStepActivation =
currentEvent as MemoryElementWithStepActivation;
AndGateActivation andGateActivation =
currentEvent as AndGateActivation;
if ( (object)memoryElementWithStepActivation != null )
print( memoryElementWithStepActivation );
else if ( (object)andGateActivation != null )
print( andGateActivation );
private void print( MemoryElementWithStepActivation _memoryElementWithStepActivation )
StringBuilder sb = new StringBuilder();
bool overflow = _memoryElementWithStepActivation.m_overflow;
, _memoryElementWithStepActivation.m_memoryElementWithStep.getName()
, _memoryElementWithStepActivation.m_prevNumber
, _memoryElementWithStepActivation.m_step
, _memoryElementWithStepActivation.m_newNumber
, _memoryElementWithStepActivation.m_overflow
sb.Append( " - overflow" );
Console.WriteLine( sb.ToString() );
private void print( AndGateActivation _andGateActivation )
StringBuilder sb = new StringBuilder();
bool overflow = _andGateActivation.m_overflow;
, _andGateActivation.m_mutableElement.getName()
, _andGateActivation.m_prevNumber
, _andGateActivation.m_numberToAdd
, _andGateActivation.m_newNumber
sb.Append( " - overflow" );
Console.WriteLine( sb.ToString() );
public List< IEvent > getEvents()
private List< IEvent > m_events;
public Logger getLogger()
public interface IElement
public interface IActiveElement
void tryActivate( Environment _environment );
public interface ISignalGenerator
void addDrivenElement( IActiveElement _element );
void tryActivateDrivenElements( Environment _environment );
IEnumerable< IActiveElement > getDrivenElementsIterable();
public abstract class ElementBase
public ElementBase( string _name )
public XGenerator( string _name )
m_drivenElements = new List< IActiveElement >();
public void resetImpetus()
public void tryActivateDrivenElements( Environment _environment )
foreach ( IActiveElement element in m_drivenElements )
element.tryActivate( _environment );
public IEnumerable< IActiveElement > getDrivenElementsIterable()
foreach( IActiveElement element in m_drivenElements )
public void addDrivenElement( IActiveElement _element )
m_drivenElements.Add( _element );
private List< IActiveElement > m_drivenElements;
public class MemoryElement
public virtual bool doesOverflow()
protected void setNumber( int _newData )
public class MutableMemoryElement
public MutableMemoryElement(
public virtual void addNumber( int _n )
setNumber( getNumber() + _n );
public class MemoryElementWithStep
public MemoryElementWithStep(
public void tryActivate( Environment _environment )
Logger logger = _environment.getLogger();
int prevNumber = getNumber();
int newNumber = getNumber();
MemoryElementWithStepActivation activationEvent = new MemoryElementWithStepActivation(
logger.addEvent( activationEvent );
public class MemoryElementWithOverflow
public MemoryElementWithOverflow(
: base( _name, _data, _step )
m_drivenElements = new List< IActiveElement >();
public void addDrivenElement( IActiveElement _element )
m_drivenElements.Add( _element );
public void tryActivateDrivenElements( Environment _environment )
foreach ( IActiveElement element in m_drivenElements )
element.tryActivate( _environment );
public IEnumerable< IActiveElement > getDrivenElementsIterable()
foreach( IActiveElement element in m_drivenElements )
public void resetImpetus()
public override bool doesOverflow()
public override void addNumber( int _n )
private List< IActiveElement > m_drivenElements;
, MemoryElement _fromElement
, MutableMemoryElement _toElement
, bool _inverting = false
m_fromElement = _fromElement;
m_toElement = _toElement;
m_inverting = _inverting;
m_modifierPow = _modifierPow;
public void tryActivate( Environment _environment )
Logger logger = _environment.getLogger();
int numberToAdd = m_fromElement.getNumber();
int modifier = ( int ) ( Math.Pow( 2.0, m_modifierPow ) + 0.1 );
int prevNumber = m_toElement.getNumber();
m_toElement.addNumber( numberToAdd );
int newNumber = m_toElement.getNumber();
AndGateActivation andGateActivation = new AndGateActivation(
, m_toElement.doesOverflow()
logger.addEvent( andGateActivation );
private MemoryElement m_fromElement;
private MutableMemoryElement m_toElement;
private bool m_inverting;
private int m_modifierPow;
public Adder( string _name, int _data )
public Counter( string _name, int _data )
public class AdderWithStep
public AdderWithStep( string _name, int _data, int _step )
: base( _name, _data, _step )
public class CounterWithStep
public CounterWithStep( string _name, int _data, int _step )
: base( _name, _data, _step )
public class AdderWithOverflow
: MemoryElementWithOverflow
public AdderWithOverflow( string _name, int _data, int _step )
: base( _name, _data, _step )
public class CounterWithOverflow
: MemoryElementWithOverflow
public CounterWithOverflow( string _name, int _data, int _step )
: base( _name, _data, _step )
public YReceiver( string _name )
public Scheme( Environment _environment )
m_environment = _environment;
m_signalGenerators = new List< ISignalGenerator >();
m_elements = new List< IElement >();
m_elementsToActivateStack = new Stack< IActiveElement >();
public void addElement( IElement _element )
m_elements.Add( _element );
public void addSignalGenerator( ISignalGenerator _signalGenerator )
m_signalGenerators.Add( _signalGenerator );
public Environment getEnvironment()
public void executeNImpetuses( int _number )
for ( int i = 0; i < _number; ++i )
int signalGeneratorToExecuteIndex = findSignalGeneratorToExecuteIndex( );
if ( signalGeneratorToExecuteIndex != -1 )
ISignalGenerator signalGenerator = m_signalGenerators[ signalGeneratorToExecuteIndex ];
List< IActiveElement > temp = new List< IActiveElement >();
temp.AddRange( signalGenerator.getDrivenElementsIterable() );
for ( int i = count - 1; i >= 0; --i )
m_elementsToActivateStack.Push( temp[ i ] );
signalGenerator.resetImpetus();
if ( m_elementsToActivateStack.Count == 0 )
IActiveElement activeElement = m_elementsToActivateStack.Pop();
activeElement.tryActivate( getEnvironment() );
private ISignalGenerator findSignalGeneratorToExecute()
int count = m_signalGenerators.Count;
for ( int i = count - 1; i >= 0; --i )
ISignalGenerator signalGenerator = m_signalGenerators[ i ];
if ( signalGenerator.hasImpetus() )
private int findSignalGeneratorToExecuteIndex()
int count = m_signalGenerators.Count;
for ( int i = count - 1; i >= 0; --i )
ISignalGenerator signalGenerator = m_signalGenerators[ i ];
if ( signalGenerator.hasImpetus() )
private void execute( ISignalGenerator _signalGenerator )
if ( !_signalGenerator.hasImpetus() )
_signalGenerator.resetImpetus();
_signalGenerator.tryActivateDrivenElements( getEnvironment() );
foreach ( ISignalGenerator signalGenerator in m_signalGenerators )
signalGenerator.nextTurn();
private Environment m_environment;
private List< ISignalGenerator > m_signalGenerators;
private List< IElement > m_elements;
private Stack< IActiveElement > m_elementsToActivateStack;
public class ReportPrinter
public ReportPrinter( int _height, int _length )
m_data = new string[ m_height, m_length ];
for ( int i = 0; i < m_length; ++i )
int maxColumnElementLength = getMaxElementLength( i );
normalizeColumn( i, maxColumnElementLength );
public int getMaxElementLength( int _columnIndex )
for ( int i = 0; i < m_height; ++i )
int elementLength = m_data[ i, _columnIndex ].Length;
if ( maxLength < elementLength )
maxLength = elementLength;
public void normalizeColumn( int _columnIndex, int _maxColumnElementLength )
for ( int i = 0; i < m_height; ++i )
string element = m_data[ i, _columnIndex ];
int elementLength = element.Length;
int lengthDifference = _maxColumnElementLength - elementLength;
if ( lengthDifference == 0 )
string spaces = new String( ' ', lengthDifference );
StringBuilder sb = new StringBuilder();
sb.AppendFormat( "{0}{1}", element, spaces );
m_data[ i, _columnIndex ] = sb.ToString();
for ( int i = 0; i < m_height; ++i )
for ( int j = 0; j < m_length; ++j )
Console.Write( "{0}\t", m_data[ i, j ] );
for ( int i = 0; i < m_height; ++i )
for ( int j = 0; j < m_length; ++j )
reportPrinter.m_data[ 0, m_columnIndexByMemoryElement[ Constants.CNTSqrtName ] + 1 ] = Constants.CNTSqrtName + " overflow";
reportPrinter.m_data[ 0, m_columnIndexByMemoryElement[ Constants.CNTResName ] ] = Constants.CNTResName;
reportPrinter.m_data[ lineIndex + 1, 0 ] = x.ToString();
reportPrinter.m_data[ lineIndex + 1, m_columnIndexByMemoryElement[ Constants.Sum1Name ] ] =
toText( m_eventsByMemoryElement[ Constants.Sum1Name ][ x - 1 ] );
bool cntSqrtOverflow = false;
List< IEvent > events = m_logger.getEvents();
foreach ( IEvent currentEvent in events )
string memoryElementName = currentEvent.getMemoryElement().getName();
( memoryElementName != Constants.Sum2Name )
&& ( memoryElementName != Constants.CNTSqrtName )
&& ( memoryElementName != Constants.CNTResName )
if ( memoryElementName == Constants.Sum2Name )
reportPrinter.m_data[ lineIndex, m_columnIndexByMemoryElement[ memoryElementName ] ] =
if ( currentEvent.isOverflow() )
reportPrinter.m_data[ lineIndex, m_columnIndexByMemoryElement[ memoryElementName ] + 1 ] = "1";
if ( x - 1 < m_eventsByMemoryElement[ Constants.Sum1Name ].Count )
reportPrinter.m_data[ lineIndex + 1, 0 ] = x.ToString();
reportPrinter.m_data[ lineIndex + 1, m_columnIndexByMemoryElement[ Constants.Sum1Name ] ] =
toText( m_eventsByMemoryElement[ Constants.Sum1Name ][ x - 1 ] );
else if ( memoryElementName == Constants.CNTSqrtName )
reportPrinter.m_data[ lineIndex, m_columnIndexByMemoryElement[ memoryElementName ] ] =
if ( currentEvent.isOverflow() )
reportPrinter.m_data[ lineIndex, m_columnIndexByMemoryElement[ memoryElementName ] + 1 ] = "1";
else if ( memoryElementName == Constants.CNTResName )
reportPrinter.m_data[ lineIndex, m_columnIndexByMemoryElement[ memoryElementName ] ] =
height += m_eventsByMemoryElement[ Constants.Sum2Name ].Count;
foreach ( IEvent currentEvent in m_eventsByMemoryElement[ Constants.CNTSqrtName ] )
if ( currentEvent.isOverflow() )
height += cntSqrtOverflow;
private void initEventsByMemoryElement()
m_eventsByMemoryElement = new Dictionary< string, List< IEvent > >();
m_eventsByMemoryElement.Add( Constants.Sum1Name, new List< IEvent >() );
m_eventsByMemoryElement.Add( Constants.Sum2Name, new List< IEvent >() );
m_eventsByMemoryElement.Add( Constants.CNTSqrtName, new List< IEvent >() );
m_eventsByMemoryElement.Add( Constants.CNTResName, new List< IEvent >() );
m_eventsByMemoryElement.Add( Constants.yName, new List< IEvent >() );
List< IEvent > events = m_logger.getEvents();
foreach ( IEvent currentEvent in events )
m_eventsByMemoryElement[ currentEvent.getMemoryElement().getName() ].Add( currentEvent );
public void initColumnIndexesByMemoryElement()
m_columnIndexByMemoryElement = new Dictionary< string, int >();
m_columnIndexByMemoryElement.Add( Constants.Sum1Name, 3 );
m_columnIndexByMemoryElement.Add( Constants.Sum2Name, 1 );
m_columnIndexByMemoryElement.Add( Constants.CNTSqrtName, 4 );
m_columnIndexByMemoryElement.Add( Constants.CNTResName, 6 );
public string toText( IEvent _event )
StringBuilder sb = new StringBuilder();
if ( _event.getMemoryElement().getName() == Constants.CNTResName )
return _event.getNewNumber().ToString();
, _event.getNumberToAdd()
private Dictionary< string, List< IEvent > > m_eventsByMemoryElement;
private Dictionary< string, int > m_columnIndexByMemoryElement;
public Lab1Printer( Logger _logger )
initEventsByMemoryElement();
initColumnIndexesByMemoryElement();
public void printModelling()
int height = getHeight();
ReportPrinter reportPrinter = new ReportPrinter( height, length );
reportPrinter.m_data[ 0, 0 ] = "x";
reportPrinter.m_data[ 0, m_columnIndexByMemoryElement[ Constants.SumResName ] ] = Constants.SumResName;
reportPrinter.m_data[ 0, m_columnIndexByMemoryElement[ Constants.SumResName ] + 1 ] = Constants.SumResName + " overflow";
reportPrinter.m_data[ 0, m_columnIndexByMemoryElement[ Constants.Sum1Name ] ] = Constants.Sum1Name;
reportPrinter.m_data[ 0, m_columnIndexByMemoryElement[ Constants.Sum2Name ] ] = Constants.Sum2Name;
reportPrinter.m_data[ 0, m_columnIndexByMemoryElement[ Constants.Sum3Name ] ] = Constants.Sum3Name;
reportPrinter.m_data[ 0, m_columnIndexByMemoryElement[ Constants.yName ] ] = Constants.yName;
reportPrinter.m_data[ lineIndex + 1, 0 ] = x.ToString();
List< IEvent > events = m_logger.getEvents();
bool prevSumResIsOverflow = false;
foreach ( IEvent sumResEvent in m_eventsByMemoryElement[ Constants.SumResName ] )
reportPrinter.m_data[ lineIndex, m_columnIndexByMemoryElement[ Constants.SumResName ] ] =
if ( !prevSumResIsOverflow )
reportPrinter.m_data[ lineIndex, m_columnIndexByMemoryElement[ Constants.xName ] ] =
reportPrinter.m_data[ lineIndex, m_columnIndexByMemoryElement[ Constants.Sum1Name ] ] =
toText( m_eventsByMemoryElement[ Constants.Sum1Name ][ x - 1 ] );
if ( sumResEvent.isOverflow() )
reportPrinter.m_data[ lineIndex, m_columnIndexByMemoryElement[ Constants.SumResName ] + 1 ] =
reportPrinter.m_data[ lineIndex, m_columnIndexByMemoryElement[ Constants.Sum2Name ] ] =
toText( m_eventsByMemoryElement[ Constants.Sum2Name ][ overflowIndex ] );
reportPrinter.m_data[ lineIndex, m_columnIndexByMemoryElement[ Constants.Sum3Name ] ] =
toText( m_eventsByMemoryElement[ Constants.Sum3Name ][ overflowIndex ] );
reportPrinter.m_data[ lineIndex, m_columnIndexByMemoryElement[ Constants.yName ] ] =
toText( m_eventsByMemoryElement[ Constants.yName ][ overflowIndex ] );
prevSumResIsOverflow = true;
prevSumResIsOverflow = false;
foreach ( IEvent currentEvent in events )
height += m_eventsByMemoryElement[ Constants.SumResName ].Count;
private void initEventsByMemoryElement()
m_eventsByMemoryElement = new Dictionary< string, List< IEvent > >();
m_eventsByMemoryElement.Add( Constants.Sum1Name, new List< IEvent >() );
m_eventsByMemoryElement.Add( Constants.Sum2Name, new List< IEvent >() );
m_eventsByMemoryElement.Add( Constants.Sum3Name, new List< IEvent >() );
m_eventsByMemoryElement.Add( Constants.SumResName, new List< IEvent >() );
m_eventsByMemoryElement.Add( Constants.yName, new List< IEvent >() );
List< IEvent > events = m_logger.getEvents();
foreach ( IEvent currentEvent in events )
m_eventsByMemoryElement[ currentEvent.getMemoryElement().getName() ].Add( currentEvent );
public void initColumnIndexesByMemoryElement()
m_columnIndexByMemoryElement = new Dictionary< string, int >();
m_columnIndexByMemoryElement.Add( Constants.xName, 0 );
m_columnIndexByMemoryElement.Add( Constants.SumResName, 1 );
m_columnIndexByMemoryElement.Add( Constants.Sum1Name, 3 );
m_columnIndexByMemoryElement.Add( Constants.Sum2Name, 4 );
m_columnIndexByMemoryElement.Add( Constants.Sum3Name, 5 );
m_columnIndexByMemoryElement.Add( Constants.yName, 6 );
public string toText( IEvent _event )
StringBuilder sb = new StringBuilder();
if ( _event.getMemoryElement().getName() == Constants.yName )
return _event.getNewNumber().ToString();
, _event.getNumberToAdd()
private Dictionary< string, List< IEvent > > m_eventsByMemoryElement;
private Dictionary< string, int > m_columnIndexByMemoryElement;
public static void Main()
XGenerator xGenerator = new XGenerator( Constants.xName );
int xMax = Initialization.xMax;
Register rg1 = new Register( Constants.RG1Name, step0 );
Adder sum1 = new Adder( Constants.Sum1Name, init0 );
AdderWithOverflow sumRes = new AdderWithOverflow( Constants.SumResName, init1, 0 );
Adder sum2 = new Adder( Constants.Sum2Name, init2 );
Adder sum3 = new Adder( Constants.Sum3Name, init3 );
Register rg2 = new Register( Constants.RG2Name, step3 );
AndGate andBetweenRG1_Sum1 = new AndGate( "&1", rg1, sum1, false );
AndGate andBetweenSum1_SumRes = new AndGate( "&2", sum1, sumRes, false );
AndGate andBetweenSum2_SumRes = new AndGate( "&3", sum2, sumRes, true );
AndGate andBetweenSum3_Sum2 = new AndGate( "&4", sum3, sum2, false );
AndGate andBetweenRG2_Sum3 = new AndGate( "&4", rg2, sum3, false );
YReceiver yReceiver = new YReceiver( Constants.yName );
xGenerator.addDrivenElement( andBetweenSum1_SumRes );
xGenerator.addDrivenElement( andBetweenRG1_Sum1 );
sumRes.addDrivenElement( yReceiver );
sumRes.addDrivenElement( andBetweenSum2_SumRes );
sumRes.addDrivenElement( andBetweenSum3_Sum2 );
sumRes.addDrivenElement( andBetweenRG2_Sum3 );
Environment environment = new Environment();
Scheme scheme = new Scheme( environment );
scheme.addElement( rg1 );
scheme.addElement( sumRes );
scheme.addElement( sum1 );
scheme.addElement( sum2 );
scheme.addElement( sum3 );
scheme.addElement( rg2 );
scheme.addElement( andBetweenRG1_Sum1 );
scheme.addElement( andBetweenSum1_SumRes );
scheme.addElement( andBetweenSum2_SumRes );
scheme.addElement( andBetweenSum3_Sum2 );
scheme.addElement( andBetweenRG2_Sum3 );
scheme.addElement( yReceiver );
scheme.addSignalGenerator( xGenerator );
scheme.addSignalGenerator( sumRes );
scheme.executeNImpetuses( xMax );
int y = yReceiver.getNumber();
Lab1Printer lab1Printer = new Lab1Printer( scheme.getEnvironment().getLogger() );