Skip to content

Commit 7ba32b6

Browse files
authored
improve submit messages (#384)
1 parent 5d2c1e2 commit 7ba32b6

File tree

13 files changed

+195
-92
lines changed

13 files changed

+195
-92
lines changed

.vscode/settings.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@
8282
"bit": "cpp",
8383
"charconv": "cpp",
8484
"execution": "cpp",
85-
"numbers": "cpp"
85+
"numbers": "cpp",
86+
"forward_list": "cpp",
87+
"print": "cpp"
8688
},
8789
"makefile.makeDirectory": "src",
8890
"c-cpp-flylint.clang.includePaths": [

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ To install or update LODA, please follow the [installation instructions](https:/
22

33
## [Unreleased]
44

5+
## v25.5.8
6+
7+
### Enhancements
8+
9+
* Improved log messages of `submit` command
10+
511
## v25.3.29
612

713
### Features

src/cmd/commands.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,7 @@ void Commands::lists() {
698698
}
699699

700700
void Commands::compare(const std::string& path1, const std::string& path2) {
701-
initLog(true);
701+
initLog(false);
702702
Program p1 = OeisProgram::getProgramAndSeqId(path1).first;
703703
Program p2 = OeisProgram::getProgramAndSeqId(path2).first;
704704
auto id_str = Comments::getSequenceIdFromProgram(p1);
@@ -709,10 +709,7 @@ void Commands::compare(const std::string& path1, const std::string& path2) {
709709
if (seq.id < manager.getStats().program_usages.size()) {
710710
num_usages = manager.getStats().program_usages[seq.id];
711711
}
712-
auto result = manager.getFinder().isOptimizedBetter(
713-
p1, p2, seq, OeisSequence::EXTENDED_SEQ_LENGTH, num_usages);
714-
if (result.empty()) {
715-
result = "Worse or Equal";
716-
}
717-
std::cout << result << std::endl;
712+
Log::get().info(manager.getFinder().compare(p1, p2, "First", "Second", seq,
713+
OeisSequence::EXTENDED_SEQ_LENGTH,
714+
num_usages));
718715
}

src/mine/README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ the [Matcher](matcher.hpp) class. If a generated program matches a sequence and
99
![Mining architecture](../../images/mining-arch.svg)
1010

1111
There are multiple generator and matcher implementations available. They are configured and combined in the central mining configuration file [miners.json](../../miners.default.json).
12+
A miner profile has the following basic properties:
13+
14+
- "enabled": Boolean to easily enable or disable a profile.
15+
- "backoff": Boolean to control the back-off strategy during sequence matching.
16+
- "overwrite": Controls whether existing programs should be overwritten. Possible values are "none", "auto" or "all".
17+
1218
See below for further details on the [program generation](#program-generation) and [sequence matching](#sequence-matching).
1319

1420
## Program Generation
@@ -115,8 +121,8 @@ Matchers are used to match generated programs to integer sequences. They include
115121

116122
Matchers perform two operations:
117123

118-
* **Reduce Sequences:** extract parameters from sequences and reduce sequences to more basic sequences.
119-
* **Extend Programs:** extend generated programs using the extracted sequence parameters so that they match a target sequence.
124+
- **Reduce Sequences:** extract parameters from sequences and reduce sequences to more basic sequences.
125+
- **Extend Programs:** extend generated programs using the extracted sequence parameters so that they match a target sequence.
120126

121127
See the examples in the following sections for better understanding of the process.
122128

src/mine/finder.cpp

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,12 @@ void Finder::notifyUnfoldOrMinimizeProblem(const Program &p,
141141
ProgramUtil::print(p, out);
142142
}
143143

144-
std::pair<std::string, Program> Finder::checkProgramExtended(
145-
Program program, Program existing, bool is_new, const OeisSequence &seq,
146-
bool full_check, size_t num_usages) {
147-
std::pair<std::string, Program> result;
144+
check_result_t Finder::checkProgramExtended(Program program, Program existing,
145+
bool is_new,
146+
const OeisSequence &seq,
147+
bool full_check,
148+
size_t num_usages) {
149+
check_result_t result;
148150

149151
// get the extended sequence and number of required terms
150152
auto num_check = OeisProgram::getNumCheckTerms(full_check);
@@ -161,57 +163,59 @@ std::pair<std::string, Program> Finder::checkProgramExtended(
161163
}
162164

163165
// the program is correct => update result
164-
result.second = program;
166+
result.program = program;
165167

166168
// auto-unfold seq operations
167169
Subprogram::autoUnfold(program);
168170

169171
// minimize based on number of terminating terms
170172
minimizer.optimizeAndMinimize(program, num_minimize);
171-
if (program != result.second) {
173+
if (program != result.program) {
172174
// minimization changed program => check the minimized program
173175
num_required = OeisProgram::getNumRequiredTerms(program);
174176
auto check_minimized =
175177
evaluator.check(program, extended_seq, num_required, seq.id);
176178
if (check_minimized.first == status_t::ERROR) {
177179
if (check_vanilla.first == status_t::OK) {
178180
// looks like the minimization changed the semantics of the program
179-
notifyUnfoldOrMinimizeProblem(result.second,
181+
notifyUnfoldOrMinimizeProblem(result.program,
180182
ProgramUtil::idStr(seq.id));
181183
}
182184
// we ignore the case where the base program has a warning and minimized
183185
// program an error, because it indicates a problem in the base program
184-
result.second.ops.clear();
186+
result.program.ops.clear();
185187
return result; // program not ok
186188
}
187189
}
188190

189191
// update result with minimized program
190-
result.second = program;
192+
result.program = program;
191193

192194
if (is_new) {
193195
// no additional checks needed for new programs
194-
result.first = "Found";
196+
result.status = "Found";
195197
} else {
196198
// now we are in the "update" case
197199
// compare (minimized) program with existing programs
198-
result.first = isOptimizedBetter(existing, result.second, seq.id,
199-
full_check, num_usages);
200+
result.status = isOptimizedBetter(existing, result.program, seq.id,
201+
full_check, num_usages);
200202
}
201203

202204
// clear result program if it's no good
203-
if (result.first.empty()) {
204-
result.second.ops.clear();
205+
if (result.status.empty()) {
206+
result.program.ops.clear();
205207
}
206208
return result;
207209
}
208210

209-
std::pair<std::string, Program> Finder::checkProgramBasic(
210-
const Program &program, const Program &existing, bool is_new,
211-
const OeisSequence &seq, const std::string &change_type,
212-
size_t previous_hash, bool full_check, size_t num_usages) {
211+
check_result_t Finder::checkProgramBasic(const Program &program,
212+
const Program &existing, bool is_new,
213+
const OeisSequence &seq,
214+
const std::string &change_type,
215+
size_t previous_hash, bool full_check,
216+
size_t num_usages) {
213217
static const std::string first = "Found";
214-
std::pair<std::string, Program> result; // empty string indicates no update
218+
check_result_t result; // empty string indicates no update
215219

216220
// additional metadata checks for program update
217221
if (!is_new) {
@@ -248,8 +252,8 @@ std::pair<std::string, Program> Finder::checkProgramBasic(
248252
}
249253

250254
// the program is correct => update result
251-
result.first = is_new ? first : change_type;
252-
result.second = program;
255+
result.status = is_new ? first : change_type;
256+
result.program = program;
253257
return result;
254258
}
255259

@@ -423,6 +427,22 @@ std::string Finder::isOptimizedBetter(Program existing, Program optimized,
423427
return not_better; // not better or worse => no change
424428
}
425429

430+
std::string Finder::compare(Program p1, Program p2, const std::string &name1,
431+
const std::string &name2, const OeisSequence &seq,
432+
size_t num_terms, size_t num_usages) {
433+
auto result = isOptimizedBetter(p1, p2, seq, num_terms, num_usages);
434+
if (!result.empty()) {
435+
lowerString(result);
436+
return name2 + " program is " + result;
437+
}
438+
result = isOptimizedBetter(p2, p1, seq, num_terms, num_usages);
439+
if (!result.empty()) {
440+
lowerString(result);
441+
return name1 + " program is " + result;
442+
}
443+
return "Both programs are equivalent";
444+
}
445+
426446
void Finder::notifyInvalidMatch(size_t id) {
427447
if (invalid_matches.find(id) == invalid_matches.end()) {
428448
invalid_matches[id] = 1;

src/mine/finder.hpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88

99
class OeisSequence;
1010

11+
struct check_result_t {
12+
std::string status;
13+
Program program;
14+
};
15+
1116
class Finder {
1217
public:
1318
Finder(const Settings &settings, Evaluator &evaluator);
@@ -22,14 +27,16 @@ class Finder {
2227
const Program &p, Sequence &norm_seq,
2328
const std::vector<OeisSequence> &sequences);
2429

25-
std::pair<std::string, Program> checkProgramExtended(
26-
Program program, Program existing, bool is_new, const OeisSequence &seq,
27-
bool full_check, size_t num_usages);
30+
check_result_t checkProgramExtended(Program program, Program existing,
31+
bool is_new, const OeisSequence &seq,
32+
bool full_check, size_t num_usages);
2833

29-
std::pair<std::string, Program> checkProgramBasic(
30-
const Program &program, const Program &existing, bool is_new,
31-
const OeisSequence &seq, const std::string &change_type,
32-
size_t previous_hash, bool full_check, size_t num_usages);
34+
check_result_t checkProgramBasic(const Program &program,
35+
const Program &existing, bool is_new,
36+
const OeisSequence &seq,
37+
const std::string &change_type,
38+
size_t previous_hash, bool full_check,
39+
size_t num_usages);
3340

3441
std::vector<std::unique_ptr<Matcher>> &getMatchers() { return matchers; }
3542

@@ -39,6 +46,10 @@ class Finder {
3946
const OeisSequence &seq, bool full_check,
4047
size_t num_usages);
4148

49+
std::string compare(Program p1, Program p2, const std::string &name1,
50+
const std::string &name2, const OeisSequence &seq,
51+
size_t num_terms, size_t num_usages);
52+
4253
private:
4354
static constexpr double THRESHOLD_BETTER = 1.05;
4455
static constexpr double THRESHOLD_FASTER = 1.1;

src/mine/generator.cpp

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -341,21 +341,8 @@ MultiGenerator::MultiGenerator(const Settings &settings, const Stats &stats,
341341

342342
// print info
343343
if (print_info) {
344-
std::string overwrite;
345-
switch (config.overwrite_mode) {
346-
case OverwriteMode::NONE:
347-
overwrite = "none";
348-
break;
349-
case OverwriteMode::ALL:
350-
overwrite = "all";
351-
break;
352-
case OverwriteMode::AUTO:
353-
overwrite = "auto";
354-
break;
355-
}
356344
Log::get().info("Initialized " + std::to_string(generators.size()) +
357-
" generators (profile: " + config.name +
358-
", overwrite: " + overwrite + ")");
345+
" generators");
359346
}
360347
}
361348

src/mine/miner.cpp

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -396,21 +396,33 @@ void Miner::reportCPUHour() {
396396
num_reported_hours++;
397397
}
398398

399-
void Miner::submit(const std::string &path, std::string id) {
399+
void Miner::submit(const std::string &path, std::string id_str) {
400+
reload();
400401
Parser parser;
401402
auto program = parser.parse(path);
402403
submit_mode = true;
403-
reload();
404-
if (id.empty()) {
405-
id = Comments::getSequenceIdFromProgram(program);
404+
if (id_str.empty()) {
405+
id_str = Comments::getSequenceIdFromProgram(program);
406+
}
407+
if (id_str.empty()) {
408+
Log::get().error("Missing sequence ID in program", true);
409+
}
410+
auto id = OeisSequence(id_str).id;
411+
id_str = ProgramUtil::idStr(id);
412+
Log::get().info("Loaded program for " + id_str);
413+
if (manager->isIgnored(id)) {
414+
Log::get().error(
415+
"Sequence " + id_str + " is ignored by the active miner profile", true);
406416
}
407417
OeisSequence seq(id);
408418
Settings settings(this->settings);
409419
settings.print_as_b_file = false;
410-
Log::get().info("Validating program for " + ProgramUtil::idStr(seq.id));
411420
Evaluator evaluator(settings);
412421
auto terms = seq.getTerms(OeisSequence::FULL_SEQ_LENGTH);
413422
auto num_required = OeisProgram::getNumRequiredTerms(program);
423+
Log::get().info(
424+
"Validating program against " + std::to_string(terms.size()) + " (>=" +
425+
std::to_string(std::min(num_required, terms.size())) + ") terms");
414426
auto result = evaluator.check(program, terms, num_required, seq.id);
415427
if (result.first == status_t::ERROR) {
416428
Log::get().error("Validation failed", false);
@@ -425,8 +437,17 @@ void Miner::submit(const std::string &path, std::string id) {
425437
const auto mode = Setup::getMiningMode();
426438
auto seq_programs = manager->getFinder().findSequence(
427439
program, norm_seq, manager->getSequences());
428-
size_t matches = 0;
440+
Log::get().info("Found " + std::to_string(seq_programs.size()) +
441+
" potential matches");
442+
size_t num_updated = 0;
443+
std::unordered_set<size_t> updated_ids;
429444
for (auto s : seq_programs) {
445+
const std::string skip_msg =
446+
"Skipping submission for " + ProgramUtil::idStr(s.first);
447+
if (updated_ids.find(s.first) != updated_ids.end()) {
448+
Log::get().info(skip_msg + ": already updated");
449+
continue;
450+
}
430451
program = s.second;
431452
updateSubmittedBy(program);
432453
auto r = manager->updateProgram(s.first, program, ValidationMode::EXTENDED);
@@ -438,21 +459,35 @@ void Miner::submit(const std::string &path, std::string id) {
438459
Comments::addComment(program,
439460
Comments::PREFIX_MINER_PROFILE + " manual");
440461
api_client->postProgram(program);
462+
} else {
463+
Log::get().info(skip_msg + ": not in client mode");
464+
}
465+
updated_ids.insert(s.first);
466+
num_updated++;
467+
} else {
468+
size_t num_usages = 0;
469+
if (seq.id < manager->getStats().program_usages.size()) {
470+
num_usages = manager->getStats().program_usages[seq.id];
441471
}
442-
matches++;
472+
auto existing = manager->getExistingProgram(s.first);
473+
auto msg = manager->getFinder().compare(
474+
program, existing, "new", "existing", seq,
475+
OeisSequence::EXTENDED_SEQ_LENGTH, num_usages);
476+
lowerString(msg);
477+
Log::get().info(skip_msg + ": " + msg);
443478
}
444479
}
445-
if (matches > 0) {
480+
if (num_updated > 0) {
446481
if (mode == MINING_MODE_LOCAL) {
447-
Log::get().info("Stored programs for " + std::to_string(matches) +
448-
" matched sequences in local programs directory");
449-
Log::get().warn("Skipping submission to server due to local mode");
482+
Log::get().info("Stored " + std::to_string(num_updated) +
483+
" programs in local programs directory");
484+
Log::get().warn("Skipping submissions to server due to local mode");
450485
} else {
451-
Log::get().info("Submitted programs for " + std::to_string(matches) +
452-
" matched sequences");
486+
Log::get().info("Submitted " + std::to_string(num_updated) +
487+
" programs to server");
453488
}
454489
} else {
455-
Log::get().info("No matches or existing programs are better");
490+
Log::get().info("No programs submitted to server");
456491
}
457492
}
458493

src/mine/miner.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,19 @@ class Miner {
2323
ValidationMode validation_mode;
2424
std::vector<Generator::Config> generators;
2525
std::vector<Matcher::Config> matchers;
26+
27+
bool usesBackoff() const {
28+
return std::any_of(matchers.begin(), matchers.end(),
29+
[](const auto &m) { return m.backoff; });
30+
}
2631
};
2732

2833
explicit Miner(const Settings &settings,
2934
ProgressMonitor *progress_monitor = nullptr);
3035

3136
void mine();
3237

33-
void submit(const std::string &path, std::string id);
38+
void submit(const std::string &path, std::string id_str);
3439

3540
void setBaseProgram(const Program &p) { base_program = p; }
3641

0 commit comments

Comments
 (0)