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

Lambda calculus, Type theory, Formal semantics, Program analysis

    Prev     Next     All lectures     Code    
StreamC.java     BIArrayC.java     Code    

Hamming's Sequence

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

// Stream declaration 
class Stream {
   public Stream () { isNull = true; }
   public boolean isNull;
   public BigInteger first;
   public Stream rest () { return null; }
}

// p is a list of prime numbers in increasing order
// + is concatenate, * is streams times
// hamming(p) = 
//    if (p == null) return null;
//    return first(p) + 
//       merge(first(p)*hamming(p), hamming(rest(p));
//
class Hamming extends Stream {
   Array primes;

   public Hamming (Array primes) {
      isNull = primes.isNull;
      first = primes.first;
      this.primes = primes;
   }

   public Stream rest () {
      return 
         new Merge(
            new Hamming(primes.rest()),
            new Times(primes.first, new Hamming(primes)));
   }
}

// Finite size array of objects as a stream
class Array extends Stream {
   BigInteger array[];
   int n;

   public Array (BigInteger a[], int m) {
      if (m < 1 || a == null) isNull = true; 
      else { isNull = false; first = a[0]; }
      n = m;
      array = a;
   }

   public Array rest () { 
      BigInteger b[] = new BigInteger[n-1];
      for (int i=0 ; i < n-1 ; i++) 
         b[i] = array[i+1];
      return new Array(b, n-1); 
   }
}

// Inputs: an integer n and a Stream s of numbers
// Output: the Stream of all tokens of s multiplied by n
class Times extends Stream {
   Stream s1;
   BigInteger multiplier;

   public Times (BigInteger n, Stream s) {
      isNull = s.isNull;
      s1 = s;
      multiplier = n;
      if (!isNull) first = n.multiply(s.first);
   }

   public Times rest() { 
      return new Times (multiplier, s1.rest()); 
   }
}

// Inputs: two streams of integers in increasing order
// Output: a stream in increasing order consisting of 
// exactly those numbers in the input streams (assume 
// only infinite streams).
class Merge extends Stream {
   Stream s1, s2;

   public Merge (Stream a, Stream b) {
      isNull = false;
      if (!a.isNull && 
          (b.isNull || 
           a.first.compareTo(b.first) < 0)) {
         s1 = a;
         s2 = b;
      } else if (!b.isNull && 
                 (a.isNull || 
                  a.first.compareTo(b.first) >= 0)) {
         s1 = b;
         s2 = a;
      } else {
         isNull = true;
      }
      if (!isNull) first = s1.first;
   }

   public Stream rest () { 
      return new Merge(s1.rest(), s2);  
   }
}

class Stream_4Frame 
   extends JFrame implements ActionListener {
   JTextArea text;
   JButton go;
   Stream s;

   public Stream_4Frame () {
      setLayout(new BorderLayout());
      setBackground(new Color(255,255,223));
      add("Center", 
          new JScrollPane(text = new JTextArea()));
      JPanel p = new JPanel();
      p.setLayout(new FlowLayout());
      p.setBackground(new Color(255,255,223));
      p.add(go = new JButton("Next"));
      add("South", p);
      add("North", 
          new JLabel("Hamming(3,5,11)",JLabel.LEFT));
      go.addActionListener(this);
      BigInteger primes[] = new BigInteger[3];
      primes[0] = new BigInteger("3");
      primes[1] = new BigInteger("5");
      primes[2] = new BigInteger("11");
      s = new Hamming(new Array(primes, 3));
   }

   public void actionPerformed (ActionEvent evt) {
      text.append(s.first.toString()+"\n");
      int p = text.getDocument().getLength();
      text.setCaretPosition(p);
      s = s.rest();
   }
}

public class stream_4 
   extends Applet implements ActionListener {
   JButton go;

   public void init () {
      setLayout(new BorderLayout());
      setBackground(new Color(255,255,223));
      add("Center", go = new JButton("Applet"));
      go.addActionListener(this);
   }

   public void actionPerformed (ActionEvent evt) {
      Stream_4Frame sf = new Stream_4Frame();
      sf.setSize(400,400);
      sf.setVisible(true);
   }
}
 -  Problem:
  Given: Set P of distinct primes.
  Produce: Distinct set of integers whose prime factors are in P.

Example: For P = {3,5,11}

Solution: 3,5,9,11,15,25,27,33,45,55,75,81,99,121,125,135 ...

Possible Program:
 For all numbers 1,2,3 ... do the following:
  If the number has only prime factors in P, print it.

This is unfortunately too slow to be of value.

Better Program

        _  5, 11, 25, 55, 121, 125, ...
       /
      /	  
   3 <
      \ 
       \_  9, 15, 27, 33, 45, 75, 81, 99, 135, ...
           3 * {3, 5, 9, 11, 15, 25, 27, 33, 45, ...}
So, generalizing:  Hamming(P) =
  if P is empty then return nothing.
   return
  First(P)
   +
  Merge(First(P)*Hamming(P), Hamming(Rest(P))).

Search space, prime list = 3,5,11:


                               (3)
                            1*{3,5,11}
              _______________/     \_______________
             /                                     \
           (5)                                     (9)
        1*{5,11}                                3*{3,5,11}
    _____/    \____                       _______/     \_____
   /               \                     /                   \
 (11)              (25)                (15)                  (27)
1*{11}           5*{5,11}            3*{5,11}             9*{3,5,11}
    \           __/   \__           __/   \__             __/   \__
     \         /         \         /         \           /         \
    (121)    (55)      (125)     (33)       (75)       (45)       (81)
   11*{11}  5*{11}   25*{5,11}  3*{11}    15*{5,11}  9*{5,11}  27*{3,5,11}
        \       \      /   \        \       /   \     /   \      /   \
         ..      ..  ..     ..       ..   ..     .. ..     ..  ..     ..

The class Hamming to the left provides a stream solution to this problem. It makes use of the Times and Merge classes of previous slides. The red lines on the left show where the output stream is referenced by s. Walking through s is done as in the previous slide.