20-CS-4003-001 Organization of Programming Languages Fall 2017
Exceptions

Lambda calculus, Type theory, Formal semantics, Program analysis

    Previous     Next     All lectures        Code     Exception Hierarchy    

Solve a Typical Logic Puzzle

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.applet.*;

class HouseConstraints extends BooleanExpression {
   UsmanPuzzle z;
   HouseConstraints (UsmanPuzzle z) { this.z = z; }

   public void eval () throws Up {
      // All house occupants are distinct
      assert_(distinct(z.house));
      // The brit is in the red house
      assert_(z.house[z.red].val().equals("brit"));
   }
}

class PositionConstraints extends BooleanExpression {
   UsmanPuzzle z;
   PositionConstraints (UsmanPuzzle z) { this.z = z; }

   public void eval () throws Up {
      // All house position occupants are distinct
      assert_(distinct(z.posit));
      // A norwegian's neighbor is in a blue house
      assert_(neighborOf("norwegian", z.house[z.blue].val(), z.posit));
      // The norwegian lives in the first house on the left
      assert_(z.posit[z.one].val().equals("norwegian"));
      // The green house is to the left of the white house
      assert_(leftOf(z.house[z.green], z.house[z.white], z.posit));
   }
}

class PetConstraints extends BooleanExpression {
   UsmanPuzzle z;
   PetConstraints (UsmanPuzzle z) { this.z = z; }

   public void eval () throws Up {
      // All people have different pets
      assert_(distinct(z.pet)); 
      // The swede owns the dog
      assert_(z.pet[z.dog].val().equals("swede"));
   }
}

class SmokeConstraints extends BooleanExpression {
   UsmanPuzzle z;
   SmokeConstraints (UsmanPuzzle z) { this.z = z; }

   public void eval () throws Up {
      // All people smoke different brands
      assert_(distinct(z.smoke)); 
      // The german smokes prince
      assert_(z.smoke[z.prince].val().equals("german"));
      // The smoker in the yellow house smokes dunhill
      assert_(z.smoke[z.dunhill].val().equals(z.house[z.yellow].val()));
      // The Pall Mall smoker keeps birds
      assert_(z.smoke[z.pall_mall].val().equals(z.pet[z.birds].val()));
      // The dunhill smoker is neighbors with the horse owner
      assert_(neighborOf(z.smoke[z.dunhill].val(), 
                        z.pet[z.horse].val(), 
                        z.posit));
      // The blend smoker is neighbors with the cat owner
      assert_(neighborOf(z.smoke[z.blend].val(), 
                        z.pet[z.cat].val(), 
                        z.posit));
   }
}

class DrinkConstraints extends BooleanExpression {
   UsmanPuzzle z;
   DrinkConstraints (UsmanPuzzle z) { this.z = z; }

   public void eval () throws Up {
      // All people drink different drinks
      assert_(distinct(z.drink)); 
      // The middle house occupant is a milk drinker
      assert_(z.posit[z.three].val().equals(z.drink[z.milk].val()));
      // The dane drinks tea
      assert_(z.drink[z.tea].val().equals("dane"));
      // The bluemaster smoker drinks beer
      assert_(z.smoke[z.bluemaster].val().equals(z.drink[z.beer].val()));
      // The coffee drinker is in the green house
      assert_(z.house[z.green].val().equals(z.drink[z.coffee].val()));
      // The blend smoker is neighbors with the water drinker
      assert_(neighborOf(z.smoke[z.blend].val(), 
                        z.drink[z.water].val(), 
                        z.posit));
   }
}

class UsmanPuzzle extends Puzzle implements Variable {
   UsmanFrame problem;
   int red=0, green=1, white=2, yellow=3, blue=4;
   int tea=0, coffee=1, milk=2, beer=3, water=4;
   int dog=0, birds=1, fish=2, cat=3, horse=4;
   int pall_mall=0, dunhill=1, blend=2, bluemaster=3, prince=4;
   int one=0, two=1, three=2, four=3, five=4;

   Choose 
      house[] = new Choose[5], // red, green, white, yellow, blue
      drink[] = new Choose[5], // tea, coffee, milk, beer, water 
      pet[]   = new Choose[5], // dog, birds, fish, cat, horse 
      smoke[] = new Choose[5], // pall mall, dunhill, blend, bluemaster, prince
      posit[] = new Choose[5]; // one, two, three, four, five;

   Constraint
      house_cons, posit_cons, pet_cons, smoke_cons, drink_cons;

   public UsmanPuzzle (UsmanFrame problem) { this.problem = problem; }
   
   public void checkit () throws Up, Out {
      problem.out.append(
          " Houses:\tred="+house[red].val()+
          "  green="+house[green].val()+
          "  yellow="+house[yellow].val()+
          "  blue="+house[blue].val()+
          "  white="+house[white].val()+"\n");
      problem.out.append(
          " Smokes:\tdunhill="+smoke[dunhill].val()+
          "  prince="+smoke[prince].val()+
          "  blend="+smoke[blend].val()+
          "  pall mall="+smoke[pall_mall].val()+
          "  blue="+smoke[bluemaster].val()+"\n");
      problem.out.append(
          " Pets:\tfish="+pet[fish].val()+
          "  dog="+pet[dog].val()+
          "  cat="+pet[cat].val()+
          "  horse="+pet[horse].val()+
          "  birds="+pet[birds].val()+"\n");
      problem.out.append(
          " Drinks:\twater="+drink[water].val()+
          "  beer="+drink[beer].val()+
          "  coffee="+drink[coffee].val()+
          "  tea="+drink[tea].val()+
          "  milk="+drink[milk].val()+"\n");
      problem.out.append(
          " Position:\t1="+posit[one].val()+
          "  2="+posit[two].val()+
          "  3="+posit[three].val()+
          "  4="+posit[four].val()+
          "  5="+posit[five].val()+"\n");
      throw new Out();
   }

   public void solve () {
      try {                 
         drink_cons = new Constraint(new DrinkConstraints(this), this);

         drink[4] = new Choose("brit german norwegian dane swede ",drink_cons);
         drink[3] = new Choose("brit german norwegian dane swede ",drink[4]);
         drink[2] = new Choose("brit german norwegian dane swede ",drink[3]);
         drink[1] = new Choose("brit german norwegian dane swede ",drink[2]);
         drink[0] = new Choose("brit german norwegian dane swede ",drink[1]);

         smoke_cons = new Constraint(new SmokeConstraints(this), drink[0]);

         smoke[4] = new Choose("brit german norwegian dane swede ",smoke_cons);
         smoke[3] = new Choose("brit german norwegian dane swede ",smoke[4]);
         smoke[2] = new Choose("brit german norwegian dane swede ",smoke[3]);
         smoke[1] = new Choose("brit german norwegian dane swede ",smoke[2]);
         smoke[0] = new Choose("brit german norwegian dane swede ",smoke[1]);

         pet_cons = new Constraint(new PetConstraints(this), smoke[0]);

         pet[4]   = new Choose("brit german norwegian dane swede ",pet_cons);
         pet[3]   = new Choose("brit german norwegian dane swede ",pet[4]);
         pet[2]   = new Choose("brit german norwegian dane swede ",pet[3]);
         pet[1]   = new Choose("brit german norwegian dane swede ",pet[2]);
         pet[0]   = new Choose("brit german norwegian dane swede ",pet[1]);

         posit_cons = new Constraint(new PositionConstraints(this), pet[0]);

         posit[4] = new Choose("brit german norwegian dane swede ",posit_cons);
         posit[3] = new Choose("brit german norwegian dane swede ",posit[4]);
         posit[2] = new Choose("brit german norwegian dane swede ",posit[3]);
         posit[1] = new Choose("brit german norwegian dane swede ",posit[2]);
         posit[0] = new Choose("brit german norwegian dane swede ",posit[1]);

         house_cons = new Constraint(new HouseConstraints(this), posit[0]);

         house[4] = new Choose("brit german norwegian dane swede ",house_cons);
         house[3] = new Choose("brit german norwegian dane swede ",house[4]);
         house[2] = new Choose("brit german norwegian dane swede ",house[3]);
         house[1] = new Choose("brit german norwegian dane swede ",house[2]);
         house[0] = new Choose("brit german norwegian dane swede ",house[1]);

         house[0].checkit(); 
      }
      catch (Out out) { 
         problem.out.append(" Done\n"); 
      }
      catch (Up up) {
         problem.out.append(" No solution found\n");
      }
   }
}

class UsmanFrame extends JFrame implements ActionListener {
   JTextArea out;
   JButton button;
        
   public UsmanFrame () {
      setLayout(new BorderLayout());
      add("Center", new JScrollPane(out = new JTextArea()));
      JPanel p = new JPanel();
      p.setLayout(new FlowLayout());
      p.setBackground(new Color(255,255,223));
      p.add(button = new JButton("Press Me"));
      add("South", p);
      button.addActionListener(this);
      out.setFont(new Font("TimesRoman", Font.PLAIN, 18));
   }

   public void doit () {
      UsmanPuzzle puzzle = new UsmanPuzzle(this);
      puzzle.solve();
   }
        
   public void actionPerformed (ActionEvent evt) {  doit(); }
}

public class Usman extends Applet implements ActionListener {
   JButton go;
	
   public void init () {
      setLayout(new BorderLayout());
      add("Center", go = new JButton("Applet"));
      go.addActionListener(this);
   }
	
   public void actionPerformed(ActionEvent evt) {
      UsmanFrame u = new UsmanFrame();
      u.setSize(900,300);
      u.setVisible(true);
   }
}

//--------------------------------------------

public class Puzzle {
   public String val () { return null; }
   public void assert_ (boolean e) throws Up { if (!e) throw new Up(); }
}

//--------------------------------------------

import java.util.*;

public class Choose implements Variable {
   Variable next_for;
   String [] strs;
	int n;
   String value;
   
   public Choose(String s, Variable next_for) {  
      this.next_for = next_for;
      StringTokenizer t = new StringTokenizer(s," ");
      n = t.countTokens();
      strs = new String[n];
      for (int i=0 ; i < n ; i++) strs[i] = t.nextToken();
   }

   public String val () { return value; }

   public void checkit () throws Up, Out {
      for (int i=0 ; i < n ; i++) {
         value = strs[i];
         try {  next_for.checkit();  } catch (Up up) { }
      }
      throw new Up();
   }
}

//--------------------------------------------

public interface Variable {  void checkit() throws Up, Out;  String val();  }

//--------------------------------------------

public class Out extends Exception { }

//--------------------------------------------

public class Up extends Exception { }

//--------------------------------------------

public class BooleanExpression {
   public void eval () throws Up {}

   public void assert_ (boolean e) throws Up { if (!e) throw new Up(); }

   public boolean distinct (Variable a[]) {
      int count=0;
      Variable b;
      try { for (count=0 ; ; count++) b = a[count]; } 
      catch (ArrayIndexOutOfBoundsException e) {}
      for (int i=0 ; i < count-1 ; i++) {
         for (int j=i+1 ; j < count ; j++) {
            if (a[i].val().equals(a[j].val())) return false; 
         }
      }
      return true;
   }

   public boolean leftOf (Variable a, Variable b, Variable c[]) {
      return ((c[0].val().equals(a.val())) &&
	      ((c[1].val().equals(b.val())) ||
	       (c[2].val().equals(b.val())) ||
	       (c[3].val().equals(b.val())) ||
	       (c[4].val().equals(b.val())))) ||
	     ((c[1].val().equals(a.val())) &&
	      ((c[2].val().equals(b.val())) ||
	       (c[3].val().equals(b.val())) ||
	       (c[4].val().equals(b.val())))) ||
	     ((c[2].val().equals(a.val())) &&
	      ((c[3].val().equals(b.val())) ||
	       (c[4].val().equals(b.val())))) ||
	     ((c[3].val().equals(a.val())) &&
	      (c[4].val().equals(b.val())));
   }

   public boolean neighborOf (String a, String b, Variable c[]) {
      return ((c[0].val().equals(b)) &&
	      (c[1].val().equals(a))) ||
	     ((c[1].val().equals(b)) &&
	      ((c[0].val().equals(a)) ||
	       (c[2].val().equals(a)))) ||
	     ((c[2].val().equals(b)) &&
	      ((c[1].val().equals(a)) ||
	       (c[3].val().equals(a)))) ||
	     ((c[3].val().equals(b)) &&
	      ((c[2].val().equals(a)) ||
	       (c[4].val().equals(a)))) ||
	     ((c[4].val().equals(b)) &&
	      (c[3].val().equals(a)));
   }
}

//--------------------------------------------

public class Constraint implements Variable {
   Variable variable;
   BooleanExpression expression;

   public String val () { return null; }

   public Constraint (BooleanExpression exp, Variable var) { 
      expression = exp; 
      variable = var; 
   }

   public void checkit () throws Up, Out {
      expression.eval();
      try { variable.checkit(); } catch (Up up) {}
   }
}

 - 
  • the Brit lives in the red house
  • the Swede keeps dogs as pets
  • the Dane drinks tea
  • the green house is on the left of the white house
  • the green house's owner drinks coffee
  • the person who smokes Pall Mall rears birds
  • the owner of the yellow house smokes Dunhill
  • the man living in the center house drinks milk
  • the Norwegian lives in the first house
  • the man who smokes blends lives next to the one who keeps cats
  • the man who keeps horses lives next to the man who smokes Dunhill
  • the owner who smokes BlueMaster drinks beer
  • the German smokes Prince
  • the Norwegian lives next to the blue house
  • the man who smokes blend has a neighbor who drinks water
Who owns the fish?