Skip to content

Commit 0792378

Browse files
committed
mar 18
1 parent 0a5ff8d commit 0792378

2 files changed

Lines changed: 68 additions & 9 deletions

File tree

S25/mar13_mbt_llm/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Livecode Vignette: Random Testing
2+
3+
* Part 1: using a reference implementation as an "oracle" for correctness.
4+
* Part 2: weaknesses of this approach, potential mitigations by...
5+
* becoming less specific (fuzzing); and
6+
* becoming more abstract (property-based testing).
7+
* Further Reading: mutating inputs in [_metamorphic_ testing](https://www.hillelwayne.com/post/metamorphic-testing/); thanks to Hillel Wayne for the reference.

S25/mar13_mbt_llm/src/generated.ts

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,11 @@ function nearest_neighbor(goal: Point, data: Point[]): Point | undefined {
174174
// { x: 7, y: 2 }
175175
// ];
176176
//
177+
178+
179+
//////////////////////////////////////////////////////////////////////////////
180+
181+
177182
// const goal: Point = { x: 6, y: 5 };
178183
// const nearest = nearest_neighbor(goal, points);
179184
// console.log(nearest); // Should output the closest point to (6, 5)
@@ -194,21 +199,68 @@ function rand_point_list(min: number, max: number, max_len: number): Point[] {
194199

195200
// console.log(rand_point_list(-100, 100, 10))
196201

202+
// In the interest of time (sorry...)
203+
let cGood = 0
204+
let cUndef = 0
205+
let cInput = 0
206+
let cNearest = 0
207+
208+
197209
function run_trial(count: number) {
198210
const goal = rand_point(0, 5)
199211
const data = rand_point_list(0, 5, 100)
200-
const expected = nearest_neighbor_reference(goal, data)
212+
// What if we can't use a reference oracle?
213+
//const expected = nearest_neighbor_reference(goal, data)
214+
201215
const actual = nearest_neighbor(goal, data)
216+
202217

203-
if(expected != actual) {
204-
console.log(`Failed on trial ${count}:`)
205-
console.log(`goal: ${JSON.stringify(goal)}`)
206-
console.log(`data: ${JSON.stringify(data)}`)
207-
console.log(`expected: ${JSON.stringify(expected)}`)
208-
console.log(`actual: ${JSON.stringify(actual)}`)
218+
//if(expected != actual) {
219+
const outcome = isValid(goal, data, actual)
220+
if(outcome !== OUTCOME.Good) {
221+
if(outcome === OUTCOME.Bad_Undefined) cUndef++
222+
if(outcome === OUTCOME.Not_In_Input) cInput++
223+
if(outcome === OUTCOME.Not_Nearest) cNearest++
224+
//console.log(`Failed on trial ${count}:`)
225+
//console.log(`goal: ${JSON.stringify(goal)}`)
226+
//console.log(`data: ${JSON.stringify(data)}`)
227+
//console.log(`expected: ${JSON.stringify(expected)}`)
228+
//console.log(`actual: ${JSON.stringify(actual)}`)
229+
230+
} else {
231+
cGood++
232+
}
233+
// :-( we could define a custom type and pass one of these
234+
//return {good: cGood, input: cInput, undef: cUndef, nearest:cNearest}
235+
}
236+
237+
enum OUTCOME {
238+
Good,
239+
Bad_Undefined,
240+
Not_In_Input,
241+
Not_Nearest
242+
}
243+
244+
function isValid(goal: Point, data: Point[], output: Point | undefined): OUTCOME {
245+
if(output === undefined ) {
246+
// The output is undefined if-and-only-if data is empty
247+
if(data.length !== 0) return OUTCOME.Bad_Undefined
248+
} else {
249+
// Property: the output must be an element of the data
250+
if(!data.includes(output)) return OUTCOME.Not_In_Input
251+
// Property: distance from output is smallest across all data
252+
for(const pt of data) {
253+
// Use taxi distance
254+
const dist = Math.abs(pt.x - goal.x) + Math.abs(pt.y - goal.y)
255+
const output_dist = Math.abs(output.x - goal.x) + Math.abs(output.y - goal.y)
256+
if(dist < output_dist)
257+
return OUTCOME.Not_Nearest
209258
}
259+
}
260+
return OUTCOME.Good
210261
}
211262

212-
for(let count=0;count<1000000;count++) {
263+
for(let count=0;count<100000;count++) {
213264
run_trial(count)
214-
}
265+
}
266+
console.log({good: cGood, input: cInput, undef: cUndef, nearest:cNearest})

0 commit comments

Comments
 (0)