// A = compressor type (e.g. s), Data = data type persistable sclass CompressionSearch_AnyType extends Probabilistic { replace Regime with CompressionRegime_AnyType. // user-set settable Regime regime; gettable Data inputData; settable long inputSize; // in bytes event onNewBest; event onDisqualified(Submission s); // public output variables new Best best; new L strategies; *() { init(); } *(Regime *regime) { init(); } *(Regime *regime, Data *inputData, long *inputSize) { 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 { if (!correct()) ret linesLL("BAD"); ret linesLL( (isHardChecked() ? " HARD " : "MAYBE ") + ifloor(score()*100), "Exact compression ratio: " + scoreRatio(), "Code:", indentx(shorten(500, str(decompressor()))), "Code as bytes:", indentx(shorten(500, 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); } simplyCached S decompressor_str() { ret strOrNull(decompressor()); } int compressedSize aka nBytes() { ret l(compressed()); } simplyCached Ratio scoreRatio() { ret Ratio(inputSize(), compressedSize()); } simplyCached double score() { ret scoreRatio()!; } bool decompressed; O decompressedValue; O decompressed() { if (!decompressed) { decompressedValue = regime.runDecompressor(decompressor()); set decompressed; } ret decompressedValue; } bool checkUnder(Regime regime) { ret checkResult(regime.runDecompressor(decompressor())); } simplyCached bool isHardChecked() { if (!correct()) false; var nextRegime = regime.harderRegime(); if (nextRegime == null) true; ret checkUnder(nextRegime); } bool checkResult(O decompressed) { ret eq(toByteList(decompressed), inputData()); } simplyCached Bool correct() { ret eq(toByteList(decompressed()), inputData()); } } // end of Submission Submission _submit(A compression, O notes) { if (compression == null) null; print("Received submission"); print("Code: " + takeFirst(500, str(compression))); 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!; } Submission bestHardSubmission() { var s = best!; if (s == null || !s.isHardChecked()) null; ret s; } A bestCompression aka get() { var s = bestSubmission(); ret s?.decompressor(); } bool has() { ret bestSubmission() != null; } void addStrategy(AbstractCompressor_AnyType compressor) { if (compressor == null) ret; initAction(compressor); compressor.setSearch(this); strategies.add(compressor); compressor.run(); } run {} }