Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/form/expression.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "form/expression.hpp"

#include <algorithm>
#include <iostream>
#include <sstream>

Expression::Expression()
Expand Down Expand Up @@ -202,6 +203,28 @@ void Expression::replaceName(const std::string& from, const std::string& to) {
}
}

void Expression::substituteFunction(const std::string& from,
const Expression& to,
const std::string& param) {
if (type == Type::FUNCTION && name == from) {
// sanity check
if (to.type != Type::FUNCTION || to.children.size() != 1) {
throw std::runtime_error("invalid function substitution: " +
to.toString());
}
name = to.name;
Expression& arg = *children.front();
Expression newArg = *to.children.front(); // copy
newArg.replaceAll(Expression(Type::PARAMETER, param), arg);
arg = newArg;
std::cout << "result " << toString() << std::endl;
return;
}
for (auto& c : children) {
c->substituteFunction(from, to, param);
}
}

std::ostream& operator<<(std::ostream& out, const Expression& e) {
e.print(out, 0, true, Expression::Type::CONSTANT);
return out;
Expand Down
3 changes: 3 additions & 0 deletions src/form/expression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ class Expression {

void replaceName(const std::string& from, const std::string& to);

void substituteFunction(const std::string& from, const Expression& to,
const std::string& param);

friend std::ostream& operator<<(std::ostream& out, const Expression& e);

std::string toString() const;
Expand Down
29 changes: 24 additions & 5 deletions src/form/formula.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "form/formula.hpp"

#include <iostream>
#include <set>

#include "form/expression_util.hpp"
Expand Down Expand Up @@ -138,6 +139,17 @@ void Formula::replaceName(const std::string& from, const std::string& to) {
entries = newEntries;
}

void Formula::substituteFunction(const std::string& from,
const Expression& to) {
const auto param = ExpressionUtil::newParameter();
for (auto& e : entries) {
std::cout << "subst " << from << " -> " << to.toString() << " in "
<< e.second.toString() << std::endl;
e.second.substituteFunction(from, to, param.name);
ExpressionUtil::normalize(e.second);
}
}

void Formula::collectEntries(const std::string& name, Formula& target) {
for (auto& e : entries) {
if (e.first.name == name) {
Expand All @@ -159,14 +171,21 @@ void Formula::collectEntries(const Expression& e, Formula& target) {
}
}

void Formula::resolveIdentities() {
void Formula::resolveIdentities(const std::string& main) {
auto copy = entries;
for (auto& e : copy) {
if (ExpressionUtil::isSimpleFunction(e.first) &&
ExpressionUtil::isSimpleFunction(e.second) &&
copy.find(e.second) != copy.end()) {
if (!ExpressionUtil::isSimpleFunction(e.first, true) ||
!ExpressionUtil::isSimpleFunction(e.second, false) ||
e.first.name == main) {
continue;
}
auto r = ExpressionUtil::newFunction(e.second.name);
if (copy.find(r) != copy.end()) {
std::cout << "candidate " << e.first.toString() << " = "
<< e.second.toString() << std::endl;
entries.erase(e.first);
replaceName(e.second.name, e.first.name);

substituteFunction(e.first.name, e.second);
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/form/formula.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ class Formula {

void replaceName(const std::string& from, const std::string& to);

void substituteFunction(const std::string& from, const Expression& to);

void collectEntries(const std::string& name, Formula& target);

void collectEntries(const Expression& e, Formula& target);

void resolveIdentities();
void resolveIdentities(const std::string& main);

void resolveSimpleFunctions();

Expand Down
8 changes: 4 additions & 4 deletions src/form/formula_gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -420,16 +420,16 @@ bool FormulaGenerator::generateSingle(const Program& p) {
formula.resolveSimpleFunctions();
Log::get().debug("Resolved simple functions: " + formula.toString());

// resolve identities
formula.resolveIdentities(getCellName(Program::OUTPUT_CELL));
Log::get().debug("Resolved identities: " + formula.toString());

// extract main formula (filter out irrelant memory cells)
Formula tmp;
formula.collectEntries(getCellName(Program::OUTPUT_CELL), tmp);
formula = tmp;
Log::get().debug("Pruned formula: " + formula.toString());

// resolve identities
formula.resolveIdentities();
Log::get().debug("Resolved identities: " + formula.toString());

// success
return true;
}
Expand Down