#define substitute__EXTRA_PARAMS , uint64_t search, uint64_t replace
#define substitute__EXTRA_PASS   , search, replace

#define substitute__FIRST_STATEMENT \
	do { \
		if(equals(a, expr, search)) { \
      return replace; \
		} \
	} while(0);

#define substitute__REAL         return expr;
#define substitute__VARIABLE     return expr;
#define substitute__BOOLEAN      return expr;
#define substitute__UNDEFINED    return expr;
#define substitute__SMALLINT     return expr;
#define substitute__LARGEINT     return expr;
#define substitute__FRACTION     return changed ? embed_fraction(a, numerator, denominator) : expr;
#define substitute__POWER        return changed ? embed_power(a, base, exponent) : expr;
#define substitute__SUM          return changed ? embed_sum(a, count, values) : expr;
#define substitute__PRODUCT      return changed ? embed_product(a, count, values) : expr;
#define substitute__EQUALS       return changed ? solver_Algebra_equals(a, lhs, rhs) : expr;
#define substitute__NOT_EQUALS   return changed ? solver_Algebra_not_equals(a, lhs, rhs) : expr;
#define substitute__LESS_THAN    return changed ? solver_Algebra_less_than(a, lhs, rhs) : expr;
#define substitute__GREATER_THAN return changed ? solver_Algebra_greater_than(a, lhs, rhs) : expr;
#define substitute__INVALID      return pack_undefined();

MAP(substitute)

uint64_t solver_Algebra_substitute(struct solver_Algebra *a, uint64_t expr, uint64_t search, uint64_t replace) {
  return substitute(a, expr, search, replace);
}