Skip to content

Commit d418a72

Browse files
authored
support div in formulas (#188)
1 parent fab77ec commit d418a72

File tree

9 files changed

+53
-18
lines changed

9 files changed

+53
-18
lines changed

CHANGELOG.md

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

77
* Fix programs update interval
88

9+
### Enhancements
10+
11+
* Support `div` in formulas
12+
913
# v22.10.14
1014

1115
### Enhancements

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Options:
5151
-t <number> Number of sequence terms (default: 10)
5252
-b Print result in b-file format from offset 0
5353
-B <number> Print result in b-file format from a custom offset
54-
-o <string> Export format (pari,loda)
54+
-o <string> Export format (formula,loda,pari)
5555
-s Evaluate program to number of execution steps
5656
-c <number> Maximum number of interpreter cycles (no limit: -1)
5757
-m <number> Maximum number of used memory cells (no limit: -1)

src/commands.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ void Commands::help() {
8282
std::cout << " -B <number> Print result in b-file format from a "
8383
"custom offset"
8484
<< std::endl;
85-
std::cout << " -o <string> Export format (pari,loda)" << std::endl;
85+
std::cout << " -o <string> Export format (formula,loda,pari)"
86+
<< std::endl;
8687
std::cout << " -s Evaluate program to number of "
8788
"execution steps"
8889
<< std::endl;
@@ -190,12 +191,18 @@ void Commands::export_(const std::string& path) {
190191
Parser parser;
191192
Program program = parser.parse(getProgramPathAndSeqId(path).first);
192193
const auto& format = settings.export_format;
193-
if (format.empty() || format == "pari") {
194-
auto formula = Formula::fromProgram(program);
194+
if (format.empty() || format == "formula") {
195+
auto formula = Formula::fromProgram(program, false);
195196
if (!formula.first) {
196197
throw std::runtime_error("program cannot be converted to formula");
197198
}
198199
std::cout << Pari::generate(formula.second) << std::endl;
200+
} else if (format == "pari") {
201+
auto formula = Formula::fromProgram(program, true);
202+
if (!formula.first) {
203+
throw std::runtime_error("program cannot be converted to pari");
204+
}
205+
std::cout << Pari::generate(formula.second) << std::endl;
199206
} else if (format == "loda") {
200207
ProgramUtil::print(program, std::cout);
201208
} else {
@@ -302,7 +309,7 @@ void Commands::testPari() {
302309
}
303310
auto seq = manager.getSequences().at(id);
304311
auto program = parser.parse(seq.getProgramPath());
305-
auto formula = Formula::fromProgram(program);
312+
auto formula = Formula::fromProgram(program, true);
306313
if (!formula.first) {
307314
continue;
308315
}

src/formula.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Expression operandToExpression(Operand op) {
4141
throw std::runtime_error("internal error"); // unreachable
4242
}
4343

44-
std::pair<bool, Formula> Formula::fromProgram(const Program& p) {
44+
std::pair<bool, Formula> Formula::fromProgram(const Program& p, bool pariMode) {
4545
std::pair<bool, Formula> result;
4646
result.first = false;
4747
Formula& f = result.second;
@@ -66,7 +66,7 @@ std::pair<bool, Formula> Formula::fromProgram(const Program& p) {
6666

6767
// update expressions using operations
6868
for (auto& op : p.ops) {
69-
if (!f.update(op)) {
69+
if (!f.update(op, pariMode)) {
7070
return result; // operation not supported
7171
}
7272
Log::get().debug("Operation " + ProgramUtil::operationToString(op) +
@@ -113,7 +113,7 @@ Expression treeExpr(Expression::Type t, const Expression& c1,
113113
return result;
114114
}
115115

116-
bool Formula::update(const Operation& op) {
116+
bool Formula::update(const Operation& op, bool pariMode) {
117117
auto source = operandToExpression(op.source);
118118
auto target = operandToExpression(op.target);
119119

@@ -139,12 +139,26 @@ bool Formula::update(const Operation& op) {
139139
entries[target] =
140140
treeExpr(Expression::Type::PRODUCT, prevTargetValue, source);
141141
return true;
142+
case Operation::Type::DIV:
143+
if (pariMode) {
144+
entries[target] = Expression(Expression::Type::FUNCTION, "truncate");
145+
entries[target].newChild(
146+
treeExpr(Expression::Type::FRACTION, prevTargetValue, source));
147+
148+
} else {
149+
entries[target] =
150+
treeExpr(Expression::Type::FRACTION, prevTargetValue, source);
151+
}
152+
return true;
142153
case Operation::Type::POW: {
143-
if (CanBeNegative(source)) {
144-
return false;
154+
if (pariMode && CanBeNegative(source)) {
155+
entries[target] = Expression(Expression::Type::FUNCTION, "truncate");
156+
entries[target].newChild(
157+
treeExpr(Expression::Type::POWER, prevTargetValue, source));
158+
} else {
159+
entries[target] =
160+
treeExpr(Expression::Type::POWER, prevTargetValue, source);
145161
}
146-
entries[target] =
147-
treeExpr(Expression::Type::POWER, prevTargetValue, source);
148162
return true;
149163
}
150164
default:

src/include/formula.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77

88
class Formula {
99
public:
10-
static std::pair<bool, Formula> fromProgram(const Program& p);
10+
static std::pair<bool, Formula> fromProgram(const Program& p, bool pariMode);
1111

1212
std::string toString() const;
1313

1414
private:
1515
std::map<Expression, Expression> entries;
1616

17-
bool update(const Operation& op);
17+
bool update(const Operation& op, bool pariMode);
1818

1919
void replaceAll(const Expression& from, const Expression& to);
2020
};

src/oeis_manager.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -645,9 +645,9 @@ void OeisManager::dumpProgram(size_t id, Program &p, const std::string &file,
645645
}
646646
}
647647
tmp.ops.push_back(nop);
648-
auto formula = Formula::fromProgram(p);
648+
auto formula = Formula::fromProgram(p, false);
649649
if (formula.first) {
650-
nop.comment = formula.second.toString();
650+
nop.comment = "Formula: " + formula.second.toString();
651651
tmp.ops.push_back(nop);
652652
}
653653
nop.comment.clear();
@@ -665,7 +665,7 @@ void OeisManager::alert(Program p, size_t id, const std::string &prefix,
665665
std::stringstream buf;
666666
buf << prefix << " program for " << seq
667667
<< " Terms: " << seq.getTerms(settings.num_terms);
668-
auto formula = Formula::fromProgram(p);
668+
auto formula = Formula::fromProgram(p, false);
669669
if (formula.first) {
670670
buf << ". Formula: " << formula.second.toString();
671671
}

src/test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -887,7 +887,7 @@ void Test::formula() {
887887
OeisSequence seq(e.first);
888888
Log::get().info("Testing formula for " + seq.id_str() + ": " + e.second);
889889
auto p = parser.parse(seq.getProgramPath());
890-
auto r = Formula::fromProgram(p);
890+
auto r = Formula::fromProgram(p, false);
891891
if (!r.first) {
892892
Log::get().error("Cannot generate formula from program", true);
893893
}

tests/formula/program-formula.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ A001478: a(n)=-n-1
1111
A002489: a(n)=n^(n^2)
1212
A005408: a(n)=2*n+1
1313
A005843: a(n)=2*n
14+
A007583: a(n)=2*((4^n)/3)+1
1415
A008785: a(n)=(n+4)^n
1516
A022958: a(n)=2-n
1617
A318791: a(n)=(3*n-38)*(3*n-39)+41

tests/programs/oeis/007/A007583.asm

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
; A007583: a(n) = (2^(2*n + 1) + 1)/3.
2+
; 1,3,11,43,171,683,2731,10923,43691,174763,699051,2796203,11184811,44739243,178956971,715827883,2863311531,11453246123,45812984491,183251937963,733007751851,2932031007403,11728124029611,46912496118443,187649984473771,750599937895083,3002399751580331,12009599006321323,48038396025285291,192153584101141163,768614336404564651,3074457345618258603,12297829382473034411,49191317529892137643,196765270119568550571,787061080478274202283,3148244321913096809131,12592977287652387236523,50371909150609548946091
3+
4+
mov $1,4
5+
pow $1,$0
6+
div $1,3
7+
mul $1,2
8+
add $1,1
9+
mov $0,$1

0 commit comments

Comments
 (0)