Skip to content

Commit

Permalink
rewrite pari tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ckrause committed Jun 21, 2024
1 parent d16abc4 commit 62ff8ef
Show file tree
Hide file tree
Showing 10 changed files with 46 additions and 97 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Options:
-t <number> Number of sequence terms (default: 8)
-b Print result in b-file format from offset 0
-B <number> Print result in b-file format from a custom offset
-o <string> Export format (formula,loda,pari)
-o <string> Export format (formula,loda,pari-function,pari-vector)
-d Export with dependencies to other programs
-s Evaluate program to number of execution steps
-c <number> Maximum number of interpreter cycles (no limit: -1)
Expand Down
5 changes: 3 additions & 2 deletions src/cmd/commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ void Commands::help() {
std::cout << " -B <number> Print result in b-file format from a "
"custom offset"
<< std::endl;
std::cout << " -o <string> Export format (formula,loda,pari)"
std::cout << " -o <string> Export format "
"(formula,loda,pari-function,pari-vector)"
<< std::endl;
std::cout
<< " -d Export with dependencies to other programs"
Expand Down Expand Up @@ -218,7 +219,7 @@ void Commands::export_(const std::string& path) {
throwConversionError(format);
}
std::cout << formula.toString() << std::endl;
} else if (format == "pari") {
} else if (format == "pari-function" || format == "pari") {
if (!generator.generate(program, -1, formula, settings.with_deps) ||
!PariFormula::convert(formula, false, pari_formula)) {
throwConversionError(format);
Expand Down
86 changes: 18 additions & 68 deletions src/cmd/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ void Test::all() {
checkpoint();
knownPrograms();
formula();
pariEval();

// slow tests
number();
Expand Down Expand Up @@ -886,92 +885,43 @@ void Test::memUsage() {
}

void Test::formula() {
checkFormulas("formula.txt", FormulaType::FORMULA);
checkFormulas("pari-function.txt", FormulaType::PARI_FUNCTION);
checkFormulas("pari-vector.txt", FormulaType::PARI_VECTOR);
}

void Test::checkFormulas(const std::string& testFile, FormulaType type) {
std::string path = std::string("tests") + FILE_SEP + std::string("formula") +
FILE_SEP + std::string("program-formula.txt");
FILE_SEP + testFile;
std::map<size_t, std::string> map;
OeisList::loadMapWithComments(path, map);
if (map.empty()) {
Log::get().error("Unexpected map content", true);
}
Parser parser;
FormulaGenerator generator;
for (auto& e : map) {
for (const auto& e : map) {
OeisSequence seq(e.first);
Log::get().info("Testing formula for " + seq.id_str() + ": " + e.second);
auto p = parser.parse(seq.getProgramPath());
Formula f;
if (!generator.generate(p, seq.id, f, true)) {
Log::get().error("Cannot generate formula from program", true);
}
if (f.toString() != e.second) {
Log::get().error("Unexpected formula: " + f.toString(), true);
}
}
}

void Test::pariEval() {
auto base_path =
std::string("tests") + FILE_SEP + std::string("formula") + FILE_SEP;
testPariEval(base_path + "program-pari-recursive.txt", false);
testPariEval(base_path + "program-pari-vector.txt", true);
}

void testPariEvalCode(const std::string& seq_id,
const std::string& expected_eval_code, bool asVector) {
Log::get().info("Testing PARI/GP " +
std::string((asVector ? "vector" : "recursive")) +
" code for " + seq_id);
Parser parser;
FormulaGenerator generator;
OeisSequence seq(seq_id);
auto program = parser.parse(seq.getProgramPath());
Formula f;
PariFormula pari;
if (!generator.generate(program, seq.id, f, true)) {
Log::get().error("Cannot generate formula from program", true);
}
if (!PariFormula::convert(f, asVector, pari)) {
Log::get().error("Cannot convert formula to PARI/GP", true);
}
std::stringstream eval_code;
pari.printEvalCode(10, eval_code);
if (eval_code.str() != expected_eval_code) {
Log::get().error("Unexpected PARI/GP code: " + eval_code.str(), true);
}
}

void Test::testPariEval(const std::string& testFile, bool asVector) {
std::ifstream file(testFile);
if (!file.is_open()) {
Log::get().error("Cannot open test file: " + testFile, true);
}
std::string line, seq_id, expected_eval_code;
Parser parser;
FormulaGenerator generator;
size_t num_tests = 0;
while (std::getline(file, line)) {
if (line.empty()) {
if (!seq_id.empty()) {
testPariEvalCode(seq_id, expected_eval_code, asVector);
seq_id.clear();
expected_eval_code.clear();
num_tests++;
if (type == FormulaType::FORMULA) {
if (f.toString() != e.second) {
Log::get().error("Unexpected formula: " + f.toString(), true);
}
} else if (line.substr(0, 2) == "\\\\") {
seq_id = line.substr(2);
trimString(seq_id);
expected_eval_code.clear();
} else {
expected_eval_code += line + "\n";
PariFormula pari;
if (!PariFormula::convert(f, type == FormulaType::PARI_VECTOR, pari)) {
Log::get().error("Cannot convert formula to PARI/GP", true);
}
if (pari.toString() != e.second) {
Log::get().error("Unexpected PARI/GP code: " + pari.toString(), true);
}
}
}
if (!seq_id.empty()) {
testPariEvalCode(seq_id, expected_eval_code, asVector);
num_tests++;
}
if (num_tests == 0) {
Log::get().error("No tests found in file: " + testFile, true);
}
}

void Test::stats() {
Expand Down
4 changes: 3 additions & 1 deletion src/cmd/test.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ class Test {

void formula();

void pariEval();
enum class FormulaType { FORMULA, PARI_FUNCTION, PARI_VECTOR };

void checkFormulas(const std::string &testFile, FormulaType type);

private:
std::vector<std::pair<Program, Program>> loadInOutTests(
Expand Down
34 changes: 19 additions & 15 deletions src/form/pari.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,23 @@ bool PariFormula::convert(const Formula& formula, bool as_vector,

std::string PariFormula::toString() const {
if (as_vector) {
return main_formula.toString("; ", false) + "; " +
initial_terms.toString("; ", false);
std::stringstream buf;
auto sorted = main_formula.getDefinitions(Expression::Type::VECTOR, true);
for (size_t i = 0; i < sorted.size(); i++) {
const auto& f = sorted.at(i);
auto key = ExpressionUtil::newFunction(f);
key.type = Expression::Type::VECTOR;
if (i > 0) {
buf << "; ";
}
if (max_initial_terms.find(f) != max_initial_terms.end()) {
buf << "if(n>" << max_initial_terms.at(f) << ", ";
buf << f << "[n] = " << main_formula.entries.at(key).toString() << ")";
} else {
buf << f << "[n] = " << main_formula.entries.at(key).toString() << "";
}
}
return buf.str();
} else {
return main_formula.toString("; ", true);
}
Expand All @@ -131,24 +146,13 @@ void PariFormula::printEvalCode(int64_t numTerms, std::ostream& out) const {
out << initial_terms.toString("\n", false) << std::endl;
} else {
// main function
out << main_formula.toString("; ", true) << std::endl;
out << toString() << std::endl;
}
const int64_t start = as_vector ? 1 : 0;
const int64_t end = numTerms + start - 1;
out << "for(n=" << start << "," << end << ",";
if (as_vector) {
auto sorted = main_formula.getDefinitions(Expression::Type::VECTOR, true);
for (const auto& f : sorted) {
auto key = ExpressionUtil::newFunction(f);
key.type = Expression::Type::VECTOR;
if (max_initial_terms.find(f) != max_initial_terms.end()) {
out << "if(n>" << max_initial_terms.at(f) << ", ";
out << f << "[n] = " << main_formula.entries.at(key).toString()
<< "); ";
} else {
out << f << "[n] = " << main_formula.entries.at(key).toString() << "; ";
}
}
out << toString() << "; ";
out << "print(a[n])";
} else {
out << "print(a(n))";
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions tests/formula/pari-function.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A000058: (a(n) = b(n)+1); (b(n) = if(n==0,1,local(l1=b(n-1)); l1*(l1+1)))
1 change: 1 addition & 0 deletions tests/formula/pari-vector.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A000058: if(n>1, b[n] = b[n-1]*(b[n-1]+1)); a[n] = b[n]+1
4 changes: 0 additions & 4 deletions tests/formula/program-pari-recursive.txt

This file was deleted.

6 changes: 0 additions & 6 deletions tests/formula/program-pari-vector.txt

This file was deleted.

0 comments on commit 62ff8ef

Please sign in to comment.