diff --git a/src/cmd/commands.cpp b/src/cmd/commands.cpp index eb36c456..b95713a1 100644 --- a/src/cmd/commands.cpp +++ b/src/cmd/commands.cpp @@ -202,6 +202,10 @@ void Commands::minimize(const std::string& path) { ProgramUtil::print(program, std::cout); } +void throwConversionError(const std::string& format) { + throw std::runtime_error("program cannot be converted to " + format); +} + void Commands::export_(const std::string& path) { initLog(true); Program program = OeisProgram::getProgramAndSeqId(path).first; @@ -210,13 +214,19 @@ void Commands::export_(const std::string& path) { FormulaGenerator generator; if (format.empty() || format == "formula") { if (!generator.generate(program, -1, formula, settings.with_deps)) { - throw std::runtime_error("program cannot be converted to formula"); + throwConversionError(format); } std::cout << formula.toString() << std::endl; } else if (format == "pari") { if (!generator.generate(program, -1, formula, settings.with_deps) || - !Pari::convertToPari(formula)) { - throw std::runtime_error("program cannot be converted to pari"); + !Pari::convertToPari(formula, false)) { + throwConversionError(format); + } + std::cout << Pari::toString(formula) << std::endl; + } else if (format == "pari-vector") { + if (!generator.generate(program, -1, formula, settings.with_deps) || + !Pari::convertToPari(formula, true)) { + throwConversionError(format); } std::cout << Pari::toString(formula) << std::endl; } else if (format == "loda") { diff --git a/src/form/pari.cpp b/src/form/pari.cpp index 6f1f88d0..c09888e1 100644 --- a/src/form/pari.cpp +++ b/src/form/pari.cpp @@ -26,20 +26,10 @@ void convertInitialTermsToIf(Formula& formula) { } } -void convertFracToPari(Expression& frac) { - std::string func = "floor"; - if (ExpressionUtil::canBeNegative(frac.children.at(0)) || - ExpressionUtil::canBeNegative(frac.children.at(1))) { - func = "truncate"; - } - Expression wrapper(Expression::Type::FUNCTION, func, {frac}); - frac = wrapper; -} - -bool convertExprToPari(Expression& expr) { +bool convertExprToPari(Expression& expr, const Formula& f, bool as_vector) { // convert bottom-up! for (auto& c : expr.children) { - if (!convertExprToPari(c)) { + if (!convertExprToPari(c, f, as_vector)) { return false; } } @@ -49,6 +39,10 @@ bool convertExprToPari(Expression& expr) { return false; } } + if (expr.type == Expression::Type::FUNCTION && as_vector && + f.containsFunctionDef(expr.name)) { + expr.type = Expression::Type::VECTOR; + } return true; } @@ -90,12 +84,20 @@ bool addLocalVars(Formula& f) { return changed; } -bool Pari::convertToPari(Formula& f) { +bool Pari::convertToPari(Formula& f, bool as_vector) { + Formula tmp; for (auto& entry : f.entries) { - if (!convertExprToPari(entry.second)) { + auto left = entry.first; + auto right = entry.second; + if (as_vector && left.type == Expression::Type::FUNCTION) { + left.type = Expression::Type::VECTOR; + } + if (!convertExprToPari(right, f, as_vector)) { return false; } + tmp.entries[left] = right; } + f = tmp; addLocalVars(f); convertInitialTermsToIf(f); return true; diff --git a/src/form/pari.hpp b/src/form/pari.hpp index 20993d1c..adc6294f 100644 --- a/src/form/pari.hpp +++ b/src/form/pari.hpp @@ -16,7 +16,7 @@ */ class Pari { public: - static bool convertToPari(Formula& f); + static bool convertToPari(Formula& f, bool as_vector = false); static std::string toString(const Formula& f);