PROGRAMMING IN HASKELL

Slides:



Advertisements
Similar presentations
CS4026 Formal Models of Computation Part II The Logic Model Lecture 6 – Arithmetic, fail and the cut.
Advertisements

CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists Dan Grossman Winter 2013.
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
0 PROGRAMMING IN HASKELL Chapter 10 - Declaring Types and Classes.
String is a synonym for the type [Char].
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 14 Functional Programming It is better to.
What is a Parser? A parser is a program that analyses a piece of text to determine its syntactic structure  3 means 23+4.
Chapter 7Louden, Programming Languages1 Chapter 7 - Control I: Expressions and Statements "Control" is the general study of the semantics of execution.
>(setf oldlist ) Constructing a list We know how to make a list in lisp; we simply write it: ‘4321( ) What if we want a new list with that list as a part?
Data Abstraction and Object- Oriented Programming CS351 – Programming Paradigms.
0 PROGRAMMING IN HASKELL Chapter 11 - The Countdown Problem.
Solving Systems of Equations
Analysis of Algorithms
CSE 341 : Programming Languages Lecture 2 Functions, Pairs, Lists Zach Tatlock Spring 2014.
1-4 6th grade math Addition Properties.
THE COUNTDOWN PROBLEM Graham Hutton University of Nottingham.
March 31, ICE 1341 – Programming Languages (Lecture #11) In-Young Ko Programming Languages (ICE 1341) Lecture #11 Programming Languages (ICE 1341)
1 Recursive algorithms Recursive solution: solve a smaller version of the problem and combine the smaller solutions. Example: to find the largest element.
More Data Types CSCE 314 Spring CSCE 314 – Programming Studio Defining New Data Types Three ways to define types: 1.type – Define a synonym for.
Chapter 13 Recursion Copyright © 2016 Pearson, Inc. All rights reserved.
What is a Parser? A parser is a program that analyses a piece of text to determine its syntactic structure  3 means 23+4.
String is a synonym for the type [Char].
A Mental Game as a Source of CS Case Studies
CSC Modeling with FD Constraints
Analysis of Algorithms
Parsing & Context-Free Grammars
Decrease-and-Conquer Approach
PROGRAMMING IN HASKELL
A.2 Simplifying Simplify means combine Like Terms.
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
A lightening tour in 45 minutes
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
Graph-Based Operational Semantics
Introduction to Algorithms
Koen Lindström Claessen
A Closer Look at Instruction Set Architectures
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
Chapter 8: Control Structures
Solve Systems of Linear Equations by Elimination
Nondeterministic Evaluation
(Slides copied liberally from Ruth Anderson, Hal Perkins and others)
PROGRAMMING IN HASKELL
Algorithm An algorithm is a finite set of steps required to solve a problem. An algorithm must have following properties: Input: An algorithm must have.
PROGRAMMING IN HASKELL
FP Foundations, Scheme In Text: Chapter 14.
C Operators, Operands, Expressions & Statements
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
Background In his classic 1972 paper on definitional interpreters, John Reynolds introduced two key techniques: Continuation-passing style - Makes.
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
Types and Classes in Haskell
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
Verifying a compiler for a simple language with exceptions (MPC 04).
CSCE 314: Programming Languages Dr. Dylan Shell
ONE and two-STEP EQUATIONS Ms. Harrison Math 8
are statements that are true for all numbers.
CSCE 314: Programming Languages Dr. Dylan Shell
PROGRAMMING IN HASKELL
Algebra 1 09/21/16 EQ: How do I solve equations with variables on both sides? HW: Due Friday pg. 95 # 1-33 all Bring textbooks tomorrow Quiz on Friday.
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
Data Structures and Algorithm Analysis Hashing
PROGRAMMING IN HASKELL
Recursive Thinking.
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
Presentation transcript:

PROGRAMMING IN HASKELL Chapter 9 - The Countdown Problem

What Is Countdown? A popular quiz programme on British television that has been running since 1982. Based upon an original French version called "Des Chiffres et Des Lettres". Includes a numbers game that we shall refer to as the countdown problem.

Example Using the numbers and the arithmetic operators 1 3 7 10 25 50 and the arithmetic operators + -   construct an expression whose value is 765

Rules All the numbers, including intermediate results, must be positive naturals (1,2,3,…). Each of the source numbers can be used at most once when constructing the expression. We abstract from other rules that are adopted on television for pragmatic reasons.

For our example, one possible solution is (25-10)  (50+1) 765 = Notes: There are 780 solutions for this example. Changing the target number to gives an example that has no solutions. 831

Evaluating Expressions Operators: data Op = Add | Sub | Mul | Div Apply an operator: apply :: Op  Int  Int  Int apply Add x y = x + y apply Sub x y = x - y apply Mul x y = x * y apply Div x y = x `div` y

Decide if the result of applying an operator to two positive natural numbers is another such: valid :: Op  Int  Int  Bool valid Add _ _ = True valid Sub x y = x > y valid Mul _ _ = True valid Div x y = x `mod` y == 0 Expressions: data Expr = Val Int | App Op Expr Expr

Return the overall value of an expression, provided that it is a positive natural number: eval :: Expr  [Int] eval (Val n) = [n | n > 0] eval (App o l r) = [apply o x y | x  eval l , y  eval r , valid o x y] Either succeeds and returns a singleton list, or fails and returns the empty list.

Formalising The Problem Return a list of all possible ways of choosing zero or more elements from a list: choices :: [a]  [[a]] For example: > choices [1,2] [[],[1],[2],[1,2],[2,1]]

Return a list of all the values in an expression: values :: Expr  [Int] values (Val n) = [n] values (App _ l r) = values l ++ values r Decide if an expression is a solution for a given list of source numbers and a target number: solution :: Expr  [Int]  Int  Bool solution e ns n = elem (values e) (choices ns) && eval e == [n]

Brute Force Solution Return a list of all possible ways of splitting a list into two non-empty parts: split :: [a]  [([a],[a])] For example: > split [1,2,3,4] [([1],[2,3,4]),([1,2],[3,4]),([1,2,3],[4])]

The key function in this lecture. Return a list of all possible expressions whose values are precisely a given list of numbers: exprs :: [Int]  [Expr] exprs [] = [] exprs [n] = [Val n] exprs ns = [e | (ls,rs)  split ns , l  exprs ls , r  exprs rs , e  combine l r] The key function in this lecture.

Combine two expressions using each operator: combine :: Expr  Expr  [Expr] combine l r = [App o l r | o  [Add,Sub,Mul,Div]] Return a list of all possible expressions that solve an instance of the countdown problem: solutions :: [Int]  Int  [Expr] solutions ns n = [e | ns'  choices ns , e  exprs ns' , eval e == [n]]

How Fast Is It? System: 2.8GHz Core 2 Duo, 4GB RAM Compiler: Example: One solution: All solutions: 2.8GHz Core 2 Duo, 4GB RAM GHC version 7.10.2 0.108 seconds 12.224 seconds solutions [1,3,7,10,25,50] 765

Can We Do Better? Many of the expressions that are considered will typically be invalid - fail to evaluate. For our example, only around 5 million of the 33 million possible expressions are valid. Combining generation with evaluation would allow earlier rejection of invalid expressions.

Fusing Two Functions Valid expressions and their values: type Result = (Expr,Int) We seek to define a function that fuses together the generation and evaluation of expressions: results :: [Int]  [Result] results ns = [(e,n) | e  exprs ns , n  eval e]

This behaviour is achieved by defining results [] = [] results [n] = [(Val n,n) | n > 0] results ns = [res | (ls,rs)  split ns , lx  results ls , ry  results rs , res  combine' lx ry] where combine' :: Result  Result  [Result]

New function that solves countdown problems: Combining results: combine’ (l,x) (r,y) = [(App o l r, apply o x y) | o  [Add,Sub,Mul,Div] , valid o x y] New function that solves countdown problems: solutions' :: [Int]  Int  [Expr] solutions' ns n = [e | ns'  choices ns , (e,m)  results ns' , m == n]

Around 10 times faster in both cases. How Fast Is It Now? Example: One solution: All solutions: solutions' [1,3,7,10,25,50] 765 0.014 seconds 1.312 seconds Around 10 times faster in both cases.

Can We Do Better? Many expressions will be essentially the same using simple arithmetic properties, such as: x  y y  x x  1 x = Exploiting such properties would considerably reduce the search and solution spaces.

Exploiting Properties Strengthening the valid predicate to take account of commutativity and identity properties: valid :: Op  Int  Int  Bool valid Add x y = True valid Sub x y = x > y valid Mul x y = True valid Div x y = x `mod` y == 0 x  y x  y && x  1 && y  1 x  y && x  1 x  y && y  1

How Fast Is It Now? Example: Valid: Around 20 times less. Solutions: 250,000 expressions 49 expressions Around 16 times less.

Around 2 times faster. One solution: All solutions: 0.007 seconds 0.119 seconds Around 11 times faster. More generally, our program usually returns all solutions in a fraction of a second, and is around 100 times faster that the original version.