untitled notebook

node v10.24.1
version: 1.0.0
endpointsharetweet
const fc = require('fast-check'); function next(outputForIndexes, datasetLength) { for (let cursor = outputForIndexes.length -1 ; cursor >= 0 ; --cursor) { outputForIndexes[cursor]++; if (outputForIndexes[cursor] < datasetLength) { return true; } outputForIndexes[cursor] = 0; } return false; } function isAssociative(datasetLength, f) { for (let a = 0 ; a !== datasetLength ; ++a) { for (let b = 0 ; b !== datasetLength ; ++b) { for (let c = 0 ; c !== datasetLength ; ++c) { if (f(f(a,b),c) !== f(a,f(b,c))) { return false; } } } } return true; } function buildAssociativeFunction(datasetLength, randNat) { const numFunOutputs = datasetLength * datasetLength; const outputForIndexes = [...Array(numFunOutputs)].map(() => randNat() % datasetLength); while (true) { const f = (a, b) => outputForIndexes[a * datasetLength + b]; if (isAssociative(datasetLength, f)) { return f; } next(outputForIndexes, datasetLength) } } function binaryAssociativeFunction(arb) { return fc.tuple( // min=3 for tests purposes, // max=3 because buildAssociativeFunction takes too long fc.set(arb, {minLength: 3, maxLength: 3, compare: (a, b) => fc.stringify(a) === fc.stringify(b)}), fc.infiniteStream(fc.nat()).noBias() ) .map(([dataset, randomStream]) => { const associativeF = buildAssociativeFunction( dataset.length, () => randomStream.next().value ); const stringifiedDataset = dataset.map(d => fc.stringify(d)); return (a, b) => { // compute index for a const stringifiedA = fc.stringify(a); let indexA = stringifiedDataset.indexOf(stringifiedA); if (indexA === -1) indexA = fc.hash(stringifiedA) % dataset.length; // compute index for b const stringifiedB = fc.stringify(b); let indexB = stringifiedDataset.indexOf(stringifiedB); if (indexB === -1) indexB = fc.hash(stringifiedB) % dataset.length; // compute answer const indexResult = associativeF(indexA, indexB); if (!(indexA in dataset)) throw new Error('unexpected: invalid indexA'); if (!(indexB in dataset)) throw new Error('unexpected: invalid indexB'); if (!(indexResult in dataset)) throw new Error('unexpected: invalid indexResult'); return dataset[indexResult]; }; }) } // Just trying with one of the generated functions const a = 'a'; const b = 'b'; const c = 'c'; const f1 = fc.sample(binaryAssociativeFunction(fc.string()), 1)[0]; console.log('a,b -> ' + f1(a, b)); console.log('(a,b),c -> ' + f1(f1(a, b), c)); console.log('b,c -> ' + f1(b, c)); console.log('a,(b,c) -> ' + f1(a, f1(b, c))); // Property to confirm it works fc.assert(fc.property( binaryAssociativeFunction(fc.string()), fc.string(), fc.string(), fc.string(), (f, a, b, c) => f(f(a,b),c) === f(a,f(b,c))))
Loading…

no comments

    sign in to comment