Organization of a simple logical logic simulator - Java

In my work, we use processors with Boolean logic programs for an industrial application. These programs can be very long and complex. They mainly consist of sets of input bits, output bits, and internal Boolean bits. These bits are then used in logical operators that lead to the output. Inputs and outputs can be either physical wired outputs or serial communication, but this is not very important.

Here is a quick, simplified example:

Inputs: input1, input2, input3; Outputs: output1, output2, output3; Boolean: bool1, bool2, bool3; Logic: assign input1 && input2 to bool1; assign input1 && bool1 to output1; assign input2 && input3 to bool2; assign output1 && bool2 to output2; assign output1 && output2 || bool2 to bool3; 

So keep in mind that I am very new to Java. I have done quite a lot of web programming (ruby, php, javascript, etc.).

Basically, what I would like the simulator to do is break the formatting of the program and allow graphical modeling. Programs can interact with each other, and thus the simulator should also be able to process several programs (and bind input / output together).

My problem starts with the organization. I would suggest that I need to have a β€œbit” class. This class will store whether the bit is set to TRUE or FALSE, the type of bit, the corresponding equation, which processor the bit is, etc.

But then I can reach the point where I have hundreds, or thousands of "bits" of copies. How can I arrange these bits? If I wanted to capture all instances, for example, from a specific processor, how could I do this?

In addition, when I change the status (TRUE or FALSE) of the input bit in the simulator, it then updates the state of several other bits. Any suggestions on this? I would like to make it as flexible as possible because I would like to add additional features. For example, certain bits may be designated as timers (it may take a certain amount of time to set them to determine when their conditions are met, or it may take a certain amount of time to delete them when their conditions are no longer fulfilled).

My initial thought was to store arrays or hashes of objects and try to somehow organize them.

I am basically looking for any suggestions. Thanks in advance.

+4
source share
1 answer

An interesting problem. You basically create a simple virtual processor with boolean values. Therefore, I would build a simulator as more processor. Thus, you will have registers (input, output or internal registers), then the logic will determine your operands. Since you are dealing only with logical logic, it is quite easy to come up with a set of operands that you need: AND, OR, NOT, XOR. For things like & &, || these operands will have two inputs and one output. But, for NOT you will have only one input and one output. Therefore, I would create a class for each operand that you want to support. And either an abstract class or an interface, all operands are expanded / implemented. This will provide an interface for the client to evaluate each operand in the same way and execute the program.

For instance:

 public class AndOperation implements Operand, Argument { private Argument argument1; private Argument argument2; private String output; public AndOperation( Argument arg1, Argument arg2 ) { this( arg1, arg2, null ); // this is for chaining where no output exists. } public AndOperation( Argument arg1, Argument arg2, String output ) { this.argument1 = arg1; this.argument2 = arg2; this.output = output; } public boolean evaluate() { return argument1.evaluate() && argument2.evaluate(); } public String getOutputRegister() { return output; } } public interface Argument { public boolean evaluate(); } public class Register implements Argument { private String name; private boolean value; public boolean evaluate() { return value; } public void setValue( boolean value ) { this.value = value; } } public class Program implements Iterable<Operand> { public Map<Register> registers; public List<Operand> operands; public void parse( InputStream stream ) { // this will take in a stream, parse it, and create the // program. Create the registers, and operands used // to evaluate the program } public void evaluate() { for( Operand op : operands ) { evaluate( op ); } } public void evaluate( Operand operand ) { boolean output = op.evaluate(); String name = op.getOutputRegister(); Register register = registers.get( name ); register.setValue( output ); } public Iterator<Operand> iterator() { return new Debugger( this ); } } public class Debugger implements Iterator<Operand> { private Program program; private int line = 0; public boolean hasNext() { return line < program.size(); } public Operand next() { Operand operand = program.getOperands().get( line ); program.evaluate( operand ); line++; return operand; } } 

This is something like this. However, one thing I would like to point out was how to easily transform multiple operands. An operand doesn't care if it reads its input from a register or another operand. Since the register and operand implement the argument, it replaces it. For example:

 Operand op = new AndOperand( register1, new OrOperand( register2, register3 ); boolean output = op.evaluate(); // this is register1 && (register2 || register3 ) 

Of course, the hard part is about to be taken apart, but it's a little hard to show in this limited space. As for the graphical representation of this, you could create something that took this program and evaluate its operand using the operand and somehow display it on the screen. This allows you to disable the debugger without much effort. You just need a little more information that your parser could create (the line number for the operand map would be useful).

+3
source

All Articles