The first thing to note is that dependancy flows only one way along each link, and what you call 'nodes' are anything but. A general-purpose graph search is inappropriate for this problem.
You can easily determine the reason this is so if you observe that your list of nodes and links between them does not in fact uniquely specify the graph you have drawn. I could flip all the gates back around, hook their output to their left input, the left input to the right, and the right to the output, or reverse the direction of all the not gates, and the lists of nodes and links you have would still be correct.
If I were to go about modelling this, I would do something entirely different:
interface Component {
boolean value();
}
class And implements Component {
Component[] inputs;
public And(Component ... inputs){ this.inputs = inputs; }
boolean value(){
for(Component c:inputs) if(!c.value()) return false;
return true;
}
}
class Or implements Component {
Component[] inputs;
public Or(Component ... inputs){ this.inputs = inputs; }
boolean value(){
for(Component c:inputs) if(c.value()) return true;
return false;
}
}
class Not implements Component {
Component input;
public Not(Component input){ this.input = input; }
boolean value(){ return !input.value(); }
}
class Input implements Component {
boolean value;
public Input(boolean value){ set(value); }
void set(boolean newValue){ this.value = value; }
boolean value(){ return value; }
}
Now that we have our basic logic gates, we can build a more complete model using them:
public static void main(String ... args){
Input a = new Input(true), b = new Input(true), c = new Input(false);
Component n1 = new Or(a, b), n2 = new And(a, b), n3 = new And(c, n2),
n4 = new Not(n2), n5 = new And(n1, n4), n6 = new Or(n2, n3),
n7 = new Not(c), n8 = new Not(n5), n9 = new And(n5, n7),
n10 = new And(c, n8), n11 = new Or(n9, n10);
Component d = n11, e = n6;
}
The resulta are then d.value()
and e.value()
. If we instead need strings that representing the values as equations, we can override the toString
method of each gate:
class And implements Component {
//...
public String toString(){
StringBuilder b = new StringBuilder("(");
for(Component c:inputs) b.append(c).append("&&");
return b.replace(b.length()-2,b.length,")").toString();
}
}
class Or implements Component {
//...
public String toString(){
StringBuilder b = new StringBuilder("(");
for(Component c:inputs) b.append(c).append("||");
return b.replace(b.length()-2,b.length,")").toString();
}
}
class Not implements Component {
//...
public String toString(){
return String.format("!%1$s",input);
}
}
Now, any Component.toString()
will return a logical expression for its value in terms of its inputs, which are themselves expressions in terms of their inputs, and so on, up to the original Input
s.