Random Testing in 321

Similar documents
Random Testing in 321

Administrative Stuff

Functional Programming - 2. Higher Order Functions

Fall 2017 Discussion 7: October 25, 2017 Solutions. 1 Introduction. 2 Primitives

Functional Programming. Pure Functional Programming

Spring 2018 Discussion 7: March 21, Introduction. 2 Primitives

Introduction to Typed Racket. The plan: Racket Crash Course Typed Racket and PL Racket Differences with the text Some PL Racket Examples

Functional abstraction. What is abstraction? Eating apples. Readings: HtDP, sections Language level: Intermediate Student With Lambda

Functional abstraction

User-defined Functions. Conditional Expressions in Scheme

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

Delayed Expressions Fall 2017 Discussion 9: November 8, Iterables and Iterators. For Loops. Other Iterable Uses

Intro. Scheme Basics. scm> 5 5. scm>

SCHEME 8. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. March 23, 2017

Higher-Order Functions

Typed Scheme: Scheme with Static Types

Typed Racket: Racket with Static Types

Macros & Streams Spring 2018 Discussion 9: April 11, Macros

Quick announcement. Midterm date is Wednesday Oct 24, 11-12pm.

Higher-Order Functions (Part I)

Fall 2018 Discussion 8: October 24, 2018 Solutions. 1 Introduction. 2 Primitives

CSE 341 Section Handout #6 Cheat Sheet

Principles of Programming Languages

Cost of Substitution

CS 61A, Fall, 2002, Midterm #2, L. Rowe. 1. (10 points, 1 point each part) Consider the following five box-and-arrow diagrams.

CS 320 Homework One Due 2/5 11:59pm

Functional Programming. Pure Functional Languages

Module 8: Local and functional abstraction

SCHEME 7. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. October 29, 2015

CS61A Midterm 2 Review (v1.1)

From FP to OOP. Start with data: class Posn { int x; int y; Posn(int x, int y) { this.x = x; this.y = y; } }

CS61A Notes 02b Fake Plastic Trees. 2. (cons ((1 a) (2 o)) (3 g)) 3. (list ((1 a) (2 o)) (3 g)) 4. (append ((1 a) (2 o)) (3 g))

An Introduction to Functions

Local definitions and lexical scope

Local definitions and lexical scope. Local definitions. Motivating local definitions. s(s a)(s b)(s c), where s = (a + b + c)/2.

Bindings & Substitution

(add1 3) 4 (check-expect (add1 3) 4)

YOUR NAME PLEASE: *** SOLUTIONS ***

Scheme Quick Reference

SCHEME The Scheme Interpreter. 2 Primitives COMPUTER SCIENCE 61A. October 29th, 2012

MORE SCHEME. 1 What Would Scheme Print? COMPUTER SCIENCE MENTORS 61A. October 30 to November 3, Solution: Solutions begin on the following page.

Working with recursion. From definition to template. Readings: HtDP, sections 11, 12, 13 (Intermezzo 2).

Structure and Interpretation of Computer Programs

Working with recursion

CS2500 Exam 2 Fall 2011

Functional Programming. Pure Functional Languages

Name EID. (calc (parse '{+ {with {x {+ 5 5}} {with {y {- x 3}} {+ y y} } } z } ) )

Documentation for LISP in BASIC

SCHEME AND CALCULATOR 5b

Comp 411 Principles of Programming Languages Lecture 7 Meta-interpreters. Corky Cartwright January 26, 2018

CS 61A Interpreters, Tail Calls, Macros, Streams, Iterators. Spring 2019 Guerrilla Section 5: April 20, Interpreters.

Racket: Modules, Contracts, Languages

Scheme Quick Reference

Streams, Delayed Evaluation and a Normal Order Interpreter. CS 550 Programming Languages Jeremy Johnson

Interpreters and Tail Calls Fall 2017 Discussion 8: November 1, 2017 Solutions. 1 Calculator. calc> (+ 2 2) 4

Types of recursion. Structural vs. general recursion. Pure structural recursion. Readings: none. In this module: learn to use accumulative recursion

GADTs. Wouter Swierstra and Alejandro Serrano. Advanced functional programming - Lecture 7. [Faculty of Science Information and Computing Sciences]

CSC 533: Programming Languages. Spring 2015

1. For every evaluation of a variable var, the variable is bound.

CS 275 Name Final Exam Solutions December 16, 2016

GADTs. Alejandro Serrano. AFP Summer School. [Faculty of Science Information and Computing Sciences]

An Explicit Continuation Evaluator for Scheme

CS115 - Module 10 - General Trees

Vectors in Scheme. Data Structures in Scheme

The Typed Racket Guide

Principles of Programming Languages Topic: Functional Programming Professor L. Thorne McCarty Spring 2003

Types of recursion. Readings: none. In this module: a glimpse of non-structural recursion. CS 135 Winter : Types of recursion 1

Racket. CSE341: Programming Languages Lecture 14 Introduction to Racket. Getting started. Racket vs. Scheme. Example.

Introduction to Scheme

GADTs. Wouter Swierstra. Advanced functional programming - Lecture 7. Faculty of Science Information and Computing Sciences

Programming Languages. Datatypes

CS3L Summer 2011 Final Exam, Part 2 You may leave when finished; or, you must stop promptly at 12:20

Project 2: Scheme Interpreter

Programming Languages. Next: Building datatypes. Suppose I wanted. Next: Building datatypes 10/4/2017. Review so far. Datatypes.

HIERARCHICAL DATA What is a Tree? How is it different from a Deep List? When would you use one over the other?

Programming Languages: Application and Interpretation

Lisp Basic Example Test Questions

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

2D Syntax. Version October 30, 2017

Scheme in Scheme: The Metacircular Evaluator Eval and Apply

Fall 2017 December 4, 2017

Wellesley College CS251 Programming Languages Spring, 2000 FINAL EXAM REVIEW PROBLEM SOLUTIONS

Comp 311: Sample Midterm Examination

Recap: ML s Holy Trinity

Fall 2017 December 4, Scheme. Instructions

Lists. CS 5010 Program Design Paradigms Bootcamp Lesson 4.1

Adding Machine Run 2

Module 10: General trees

Trees. Binary arithmetic expressions. Visualizing binary arithmetic expressions. ((2 6) + (5 2))/(5 3) can be defined in terms of two smaller

(Provisional) Lecture 08: List recursion and recursive diagrams 10:00 AM, Sep 22, 2017

Trees. Readings: HtDP, sections 14, 15, 16.

Principles of Programming Languages

Fall Semester, The Metacircular Evaluator. Today we shift perspective from that of a user of computer langugaes to that of a designer of

Programming Languages

CS 314 Principles of Programming Languages

Principles of Programming Languages

Chapter 15 Functional Programming Languages

Programming Languages

Scheme as implemented by Racket

How to Design Programs

Transcription:

Random Testing in 321 1

Test Cases So Far Each test relates a particular input to a particular output. (test (bound-ids (with 'x (id 'y) (id 'x))) '(x)) (test (binding-ids (with 'x (id 'y) (id 'x))) '(x)) 2

Property-based Testing But we can only write so many tests by hand. To find additional bugs, we can automate testing. We start with what we hope is a fact about our program. For example, If bound-ids says 'x is bound, then binding-ids says 'x is binding. 3

Property Violation If we can find some WAE for which the property doesn t hold... (define a-wae...) (bound-ids a-wae) ; '(x) (binding-ids a-wae) ; '()... we ve found a bug. 4

Property Testing We can test this property in the usual style. ; bound=>binding? : WAE -> boolean ; checks if bound ids are also binding (define (bound=>binding? e)...) (test (bound=>binding? (id 'x)) true) (test (bound=>binding? (with 'x (num 0) (id 'x))) true) Expected result is always true, so if we had lots of WAEs, then we d have lots of tests. 5

Automated Property Testing Write a program to generate test inputs! 6

Random WAEs ; random-wae: -> WAE (define (random-wae) (case (random 5) [(0) (num (random-nat))] [(1) (id (random-symbol))] [(2) (add (random-wae) (random-wae))] [(3) (sub (random-wae) (random-wae))] [(4) (with (random-symbol) (random-wae) (random-wae))])) Watch out that code is buggy... (read on for why) 7

Random WAEs ; random-nat: -> nat (define (random-nat) (case (random 2) [(0) 0] [(1) (add1 (random-nat))])) ; random-symbol: -> symbol (define (random-symbol) (random-elem '(x y z a b c))) ; random-elem: (listof X) -> X (define (random-elem xs) (list-ref xs (random (length xs)))) 8

Generation Strategy To build a WAE, 1/5 of the time, build a number 1/5 of the time, build a symbol 3/5 of the time, first build two more WAEs 9

Expected Progress On average, we reduce the problem from Generate 1 WAE. to Generate 1.2 WAEs. since 1.2 = (2/5)*0 + (3/5)*2 10

Height Bound Limit WAE size by bounding tree height. ; random-wae/b: nat -> WAE (define (random-wae/b h) (case (random (if (zero? h) 2 5)) [(0) (num (random-nat))] [(1) (id (random-symbol))] [(2) (add (random-wae/b (sub1 h)) (random-wae/b (sub1 h)))] [(3) (sub (random-wae/b (sub1 h)) (random-wae/b (sub1 h)))] [(4) (with (random-symbol) (random-wae/b (sub1 h)) (random-wae/b (sub1 h)))])) (Alternatively, tweak weights.) 11

Property Implementation ; bound=>binding: WAE -> boolean (define (bound=>binding e) (sublist? (bound-ids e) (binding-ids e))) ; sublist?: (listof X) (listof X) -> boolean ; Expects xs and ys to be sorted and have no dups. (define (sublist? xs ys) (cond [(null? xs) #t] [(null? ys) #f] [(equal? (car xs) (car ys)) (sublist? (cdr xs) (cdr ys))] [else (sublist? xs (cdr ys))])) 12

Running Tests ; test-bound=>binding: nat nat -> (or 'passed WAE) (define (test-bound=>binding size attempts) (if (zero? attempts) 'passed (let ([test-input (random-wae/b size)]) (if (bound=>binding test-input) (test-bound=>binding size (sub1 attempts)) test-input)))) (test-bound=>binding 5 1000) 13

HW2 Test Results We ran random tests on a past year s HW2 submissions. Received 99 submissions (includes multiple attempts from the same person) Tested 6 properties Found a bug in 53 out of those 99 submissions 14

Interpreter Properties Interpreter does not crash Produces same result as another implementation (e.g., DrRacket) Type checker accurately predicts result (later) Program equivalences hold 15

With Enclosing Example For example, we should be able to replace any subexpression with a new variable. {+ 1 2} {with {x 2} {+ 1 x}} 16

Another example: {with {x {+ 5 26}} {- x 4}} {with {z {+ 5 26}} {with {x z} {- x 4}}} 17

Transformation Strategy Generate a random path for a WAE expression tree Pick a subexpression based on the path to bind to a new id Replace subexpression with a bound occurrence of the id 18

Generating Random Paths Automatically pick leaf nodes Flip a coin to determine whether we move further down the tree Because we are "lifting" a subexpression out of its original context, we only pick expressions which will not contain free id s Always pick the named-expr of the first with we encounter 19

Path Generation Implementation ; coin-flip: boolean (define (coin-flip) (zero? (random 2))) ; weighted-chance: number -> boolean (define (weighted-chance pct) (<= (random) (/ pct 100))) 20

Path Generation Implementation ; random-path: WAE -> (listof symbol) (define (random-path wae) (type-case WAE wae [num (n) empty] [id (x) empty] [with (name named-expr body) '(left)] [else (if (weighted-chance 20) empty (if (coin-flip) (cons 'left (random-path (get-branch 'left wae))) (cons 'right (random-path (get-branch 'right wae)))))] 21

Path Generation Implementation ; get-branch: symbol WAE -> WAE (define (get-branch choice wae) (type-case WAE wae [add (lhs rhs) (case choice [(left) lhs] [(right) rhs])] [sub (lhs rhs) (case choice [(left) lhs] [(right) rhs])] [with (name named-expr body) (case choice [(left) named-expr] [(right) body])] [else wae])) 22

Extracting the Subexpression Given a path, we find the subexpression: ; pick-subexpr: WAE (listof symbol) -> WAE (define (pick-subexpr wae path) (cond [(empty? path) wae] [else (pick-subexpr (get-branch (car path) wae) (cdr path))])) 23

Replacing with the New ID ; swap-subexpr WAE (listof symbol) symbol -> WAE (define (swap-subexpr wae path new-id) (cond [(empty? path) (id new-id)] [else (type-case WAE wae [add (lhs rhs) (swap-in-bop path new-id add lhs rhs)] [sub (lhs rhs) (swap-in-bop path new-id sub lhs rhs)] [with (name named-expr body) (with name (id new-id) body)] [else wae])])) 24

Replacing with the New ID (define (swap-in-bop path new-id op lhs rhs) (case (car path) [(left) (op (swap-subexpr lhs (cdr path) new-id) rhs)] [(right) (op lhs (swap-subexpr rhs (cdr path) new-id))])) 25

Implementing the Transformation ; rand-sym-not-in: (listof symbol) -> symbol (define (rand-sym-not-in lst) (let ([leftover (remove* lst syms)]) (list-ref leftover (random (length leftover))))) ; wae->with-wae: WAE -> WAE (define (wae->with-wae wae) (let* ([path (random-path wae)] [subexpr (pick-subexpr wae path)] [new-id (rand-sym-not-in (binding-ids wae))] (with new-id subexpr (swap-subexpr wae path new-id)))) 26

Putting It All Together We generate 1000 WAE s and compare interpreter output for the original and transformed programs: (for ([i (in-range 0 1000)]) (let* ([wae (random-wae/b 2 '())] [new-wae (wae->with-wae wae)]) (test (interp wae) (interp new-wae)))) 27

What Went Wrong? Our random WAE generator builds arbitrary expressions Probability we generate a WAE with free identifiers is very high 28

Eliminating Free ID s from the Random Generator ; rand-sym-from: (listof symbol) -> symbol (define (rand-sym-from ss) (list-ref ss (random (length ss)))) 29

Eliminating Free ID s from the Random Generator (define (random-wae/b h bindingids) (case (random (if (zero? h) 2 5)) [(0) (num (random-nat))] [(1) (if (empty? bindingids) (num (random-nat)) (id (rand-sym-from bindingids)))] [(2) (add (random-wae/b (sub1 h) bindingids) (random-wae/b (sub1 h) bindingids))] [(3) (sub (random-wae/b (sub1 h) bindingids) (random-wae/b (sub1 h) bindingids))] [(4) (let ([new-id (random-symbol)]) (with new-id (random-wae/b (sub1 h) bindingids) (random-wae/b (sub1 h) (cons new-id bindingids))))]) 30