20-CS-4003-001 Organization of Programming Languages Fall 2018
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. ```