// A = compressor type (e.g. s), Data = data type persistable sclass CompressionSearch_AnyType extends Probabilistic { // user-set settable CompressionRegime_AnyType regime; settable Data inputData; event onNewBest; event onDisqualified(Submission s); // public output variables new Best best; new L strategies; *() { init(); } *(CompressionRegime_AnyType *regime) { init(); } *(CompressionRegime_AnyType *regime, Data *inputData) { init(); } void init { best.onChange = r newBest; } // can submit concurrently! Submission submit(A compression, O notes default null) { ret _submit(compression, notes); } // private (although Submission is returned) class Submission { settable O notes; toString { ret linesLL( "Compressor " + (correct() ? "correct" : "incorrect"), "Compression factor " + score(), "Code:", indentx(str(decompressor())), "Code as bytes:", indentx(bytesToHex(compressed())) ); } void setDecompressor(A decompressor) { this.decompressor_cache = decompressor; } Data inputData() { ret inputData; } simplyCached byte[] compressed() { ret decompressor_cache == null ?: regime.decompressorToBytes(decompressor_cache); } simplyCached A decompressor() { ret compressed_cache == null ?: regime.decompressorFromBytes(compressed_cache); } int compressedSize aka nBytes() { ret l(compressed()); } simplyCached double score() { ret doubleRatio(inputDataSize(), compressedSize()); } bool decompressed; O decompressedValue; O decompressed() { if (!decompressed) { decompressedValue = regime.runDecompressor(decompressor()); set decompressed; } ret decompressedValue; } simplyCached Bool correct() { ret eq(toByteList(decompressed()), inputData()); } } int inputDataSize() { ret l(inputData); } Submission _submit(A compression, O notes) { if (compression == null) null; print("Received submission"); new Submission s; s.notes(notes); print("Notes: " + takeFirst(500, str(notes))); s.setDecompressor(compression); print("Size: " + nBytes(s.nBytes())); if (s.score() > best.score()) if (!s.correct()) { warn("Compressor didn't verify"); disqualified(s); } else { print("Score: " + s.score()); best.put(s, s.score(); } ret s; } Submission bestSubmission() { methodForEach flush(strategies); ret best!; } A bestCompression aka get() { var s = bestSubmission(); ret s?.decompressor(); } void addStrategy(AbstractCompressor_AnyType compressor) { if (compressor == null) ret; initAction(compressor); compressor.setSearch(this); strategies.add(compressor); compressor.run(); } run {} }