Class 26 4 November 2019 Queues and amortized analysis Rackette - - PowerPoint PPT Presentation

class 26 4 november 2019
SMART_READER_LITE
LIVE PREVIEW

Class 26 4 November 2019 Queues and amortized analysis Rackette - - PowerPoint PPT Presentation

Class 26 4 November 2019 Queues and amortized analysis Rackette operations in detail Abstract Data Types Value of abstraction Simplicity given generality Build a stack ADT once, use it in a million places Substitutability


slide-1
SLIDE 1

Class 26 4 November 2019

Queues and amortized analysis Rackette operations in detail

slide-2
SLIDE 2

Abstract Data Types

  • Value of abstraction

– Simplicity given generality

  • Build a stack ADT once, use it in a million places

– Substitutability – Data hiding

slide-3
SLIDE 3

Implementation Neutrality

  • When we use a module that meets the

module type Stack, we know that we can replace it with any other module that meets that same requirement!

slide-4
SLIDE 4

Maintaining Invariants

  • Example: In a binary search tree (which

we'll encounter very soon), every value in the left child of a node must be less than the value at the node.

  • That's an invariant of the data structure
  • If access to the data structure is limited,

we can ensure that all accesses maintain this invariant

slide-5
SLIDE 5

Stack review

module ListStack = { type stack('a) = Stack (list('a)); let empty: stack('a) = Stack([]); let isEmpty: stack('a) => bool = s => (s == empty); let push: ('a, stack('a)) => stack('a) = (datum, Stack(lst)) => Stack ([datum,...lst]); let pop : stack('a) => stack('a) = fun | Stack([]) => failwith("Can't pop from empty stack.") | Stack([hd, ...tl]) => Stack(tl); let top: stack('a) => 'a = fun | Stack([]) => failwith("Empty stack has no top element.") | Stack([hd, ...tl]) => hd; };

runtime performance?

slide-6
SLIDE 6

Stack summary

slide-7
SLIDE 7

Queue review

  • Like lining up to get on a bus
  • “First in, first out”, or FIFO
slide-8
SLIDE 8

ADT

module type Queue = { type queue; let emptyQ; let enq: (int, queue) => queue; let deq: queue => queue; let first: queue => int; };

slide-9
SLIDE 9

One implementation: two-list queue

module type Queue = { type queue; let emptyQ; let enq: (int, queue) => queue; let deq: queue => queue; let first: queue => int; }; module TwoListQueue : Queue = { type queue = (list(int), list(int)); let emptyQ = ([], []); let enq: (int, queue) => queue = (num, (front, back)) => (front, [num, ... back]); let rec deq: queue => queue = fun ... };

slide-10
SLIDE 10

Alternative implementation

  • Our two-list queue:

module TwoListQueue : Queue = { type queue = (list(int), list(int)); let emptyQ = ([], []); let enq: (int, queue) => queue = (num, (front, back)) => (front, [num, ... back]); let rec deq: queue => queue = fun ... };

slide-11
SLIDE 11

Alternative implementation

  • A two-stack queue.
  • pen ListStack;

module TwoStackQueue : Queue = { type queue = (stack(int), stack(int)); let emptyQ = (empty, empty); let enq: (int, queue) => queue = (num, (front, back)) => (front, push(num, back)); let rec deq: queue => queue = fun ... };

slide-12
SLIDE 12

Let's back up and do something basic…

slide-13
SLIDE 13

Another Implementation of Queue ADT: ListQueue

slide-14
SLIDE 14

Does the two-list queue do any better?

  • Two lists!
  • enq: push things onto list 1 (the "back"
  • f the queue). O(n -> 1)
  • deq: pop things off of stack 2 (the "front
  • f the queue") O(n -> 1) (usually)
  • peek: look at stack2’s top element O(n-

>1) (usually)

slide-15
SLIDE 15

Analysis Problem/Partial Solution

slide-16
SLIDE 16

Amortized analysis

slide-17
SLIDE 17

What if you deq twice in a row?

slide-18
SLIDE 18

Clever amortized analysis for 2-stack queue

slide-19
SLIDE 19

Rackette Examples

  • First in hideous detail…
  • Then a little faster
  • Every question-mark is a point for class

discussion.

slide-20
SLIDE 20

(define a 3)

  • The concrete program has three "pieces", each of them a list.
  • first one: List([Symbol("define"), Symbol("a"), Num(3)])
  • Parse converts this to an abstract program piece:

type abstractProgramPiece = | Definition(definition) | Expression(expression);

  • Which kind is it? How do you know?
  • A "Definition" of course! Starts with the symbol "define"
  • Data associated to a Definition:

type definition = (name, expression);

  • "name" will be "a", "expression" will be the "3"…

type name = ID(string); type expression = | Num(int) | Bool(bool) | ...

slide-21
SLIDE 21

(define a 3)

Definition( (ID("a"), Num(3) )

  • We "process" a definition by creating a new TLE containing a binding from the ID to the value of the

expression

  • Notice: a binding associates an ID (or "name") to a value

type value = | VNum(int) | VBool(bool) | VList(list(value)) | VBuiltin(string, list(value) => value) | VClosure(list(name), expression, environment) and environment = (list(binding)) and binding = (name, value);

  • What we've got --- Num(3) --- is not a value; it's an expression.
  • "evaluation" converts expressions to values!
slide-22
SLIDE 22

(define a 3)

let addDefinition = fun | (env, (id, expr)) => … let process: abstractProgram => list(value) = pieces => { let rec processHelper: (environment, abstractProgram) => list(value) = (tle, pieces) => switch (pieces) { | [] => [] | [Definition(d), ...tl] => processHelper(addDefinition((tle, d)), tl) | [Expression(e), ...tl] => [ eval((tle, [], e)), ...processHelper(tle, tl), ] }; processHelper(initialTle, pieces); };

slide-23
SLIDE 23

After processing (define a 3)

  • The (new) TLE contains a binding

Name(ID("a")) -> Vnum(3)

slide-24
SLIDE 24

Simplified version

  • Skip all parsing steps
  • Skip details of adding a binding to an

envt

slide-25
SLIDE 25

(define a 3)

  • It’s a definition
  • 2nd item must be an identifier

– Check!

  • 3rd item must be an expression

– Check!

  • Evaluate 3rd item

– Value is the number 3

  • Add binding to TLE a -> 3.
  • More precisely, Name(ID("a")) -> VNum(3)

+ -> addn builtin proc * -> mult builtin proc cons -> cons builtin proc … a -> 3

slide-26
SLIDE 26

(+ 3 2)

  • It’s a procedure-application expr
  • 1st item must be evaluate to a proc

– Check!

  • Evaluate other items to get “actuals”

– which are? [What data types?]

  • Apply proc to actual args to get value
  • Print value (because it’s a top-level

expression)

  • "5"

+ -> addn builtin proc * -> mult builtin proc cons -> cons builtin proc …

slide-27
SLIDE 27

(let ((a 2)) (+ a 1))

  • It’s a let-expression
  • 2nd item is a list of ident-exp pairs
  • 3rd item must be an expression
  • Temporarily extend current envt

with new bindings from 2nd item

  • Evaluate 3rd item in extended envt

– Get 3

  • Remove temporary bindings
  • Note the “lookup from the bottom” rule

+ -> addn builtin proc * -> mult builtin proc cons -> cons builtin proc …

a -> 2