Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Organizing Simple Boolean Logic Simulator - Java

Tags:

java

At my work we utilize processors with boolean logic programs for an industrial application. These programs can get very long and complex. They basically consist of sets of input bits, output bits, and internal boolean bits. These bits are then used in logic statements that result in the outputs. The inputs and outputs can be either physical wire outputs or serial communication, but that's not really important.

Here's 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'm very new to Java. I've done quite a bit of web based programming (ruby, php, javascript, etc).

Basically what I'd like the simulator to do is break down the formatting of the program and allow for graphically simulation. The programs can communicate to each other, and thus the simulator should be able to handle multiple programs as well (and tie the I/O together).

My problem is getting started with organization. I'd assume that I need to have a "bit" class. This class would store whether the bit is set to TRUE or FALSE, the type of bit, the relevant equation, what processor the bit is from, etc.

But then, I can get to the point where I have hundreds, or thousands of "bit" instances. How I can organize these bits then? If I wanted to grab all instances that are from, for example, a certain processor, how could I accomplish that?

Also, when I change the status (TRUE or FALSE) of an input bit within the simulator, it will then update the status of several other bits. Any suggestions on this? I'd like to make this as flexible as possible because i'd like to add additional functionality. For example, certain bits can be designated as timers (it can take a certain amount of time for them to set when their conditions are met, or it can take a certain amount of time for them to drop away when their conditions are no longer met).

My initial thought was to keep arrays or hashes of the objects and attempt to keep them organized somehow in that way.

I'm basically looking for any suggestions. Thanks in advance.

like image 724
RyanB Avatar asked Oct 09 '22 15:10

RyanB


1 Answers

Interesting problem. You are basically building a simple virtual processor of boolean values. So I would build the simulator as more of a processor. So essentially you'll have registers (input, output, or internal registers), then the logic would define your operands. Since you are only dealing with boolean logic it's pretty easy to come up with a set of operands that you need: AND, OR, NOT, XOR. For things like &&, || those operands will have two inputs and one output. But, for NOT you'll have only one input and one output. So I'd create a Class for each operand you want to support. And either an abstract Class or interface all operands extend/implement. That will provide the interface for the client to evaluate each operand in the same manner and execute the program.

For example:

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;
   }
}

That's roughly it. However, one thing I wanted to point out was how chaining multiple operands together can be transparently done. The operand doesn't care if it's reading its input from a register or another operand. Since the Register and Operand implements Argument then it substituted for either. So for example:

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

Of course the tricky part is going to be parsing it, but that's a little difficult to show in this limited space. As far as graphically representing this you could build something that took this program and evaluated it operand by operand and rendered it to the screen in some way. It's possible to build a debugger off of this without much more effort. Just need a little more information that your parser could create (line number to operand map would be helpful).

like image 71
chubbsondubs Avatar answered Oct 12 '22 05:10

chubbsondubs