A flattened loop structure

Previous    Next    Home    Applet    Source    Package

The loop structure is flattened. Each Choose object executes the for loop for a particular variable. Each for loop is linked, in order of nesting, through the Choose constructor. The Evaluate object eval solves the problem and must be linked to the most deeply nested loop. But that means it should be the same type as Choose, which creates a problem. The problem is solved by defining a Variable interface which is implemented by Evaluate and Choose. The interface requires checkit() which is the method that either loops through variable values in the case of Choose objects or evaluates the given expression in the case of eval. The interface also requires implementing v() which returns the current value of a Choose object and is used by eval to instantiate values for testing in the given logic expression.

The code is a bit awkward, though, because a set method is needed in the Evaluate class so that eval knows what Variable object values to apply to its logical expression - these cannot be given to eval when it is created because it must be created before the Choose objects. One solution, shown in the next slide, is to create the variables from within the Evaluate object.

   import java.awt.*; 
   import java.awt.event.*; 
   import javax.swing.*; 
   import java.applet.*;
   // Use interface to hook all the variables and the evaluator together
   // A 'Variable' must have a value (v) AND a connector to the next 
   // nested for loop (checkit).
   interface Variable { boolean checkit();  int v();  }
   class Choose implements Variable {
      Variable next_for;
      int val = 0;
      Choose (Variable next_for) { this.next_for = next_for; }
      public boolean checkit () {
         for ( ; val < 2 ; val++) if (next_for.checkit()) return true;
         val = 0;
         return false;
      public int v() { return val; }
   class Evaluate implements Variable {
      Variable i,j,k;
      B problem;
      public Evaluate (B problem) {  this.problem = problem; }
      void set (Choose i, Choose j, Choose k) { this.i = i; this.j = j; this.k = k; }
      public boolean checkit () {
         if ( (((1-i.v())*j.v() + i.v()*(1-k.v()) + (1-j.v())*k.v()) % 2) == 1 ) {
            problem.out.append("i="+i.v()+" j="+j.v()+" k="+k.v()+"\n");
            return true;
         return false;
      public int v() { return 0; }
   public class B extends Applet implements ActionListener {
      JTextArea out;
      JButton button;
      public void init () {
         setLayout(new FlowLayout());
         add(new JScrollPane(out = new JTextArea(16,30)));
         add(button = new JButton("Press Me"));
      public void doit() {
         out.append("\nSolve: ((1-i)*j + i*(1-k) + (1-j)*k)\n\n");
         Evaluate eval = new Evaluate(this);
         Choose k = new Choose(eval);
         Choose j = new Choose(k);
         Choose i = new Choose(j);
         if (!i.checkit()) out.append("There is no solution!\n");
      public void actionPerformed (ActionEvent evt) {  doit(); }