RGJW3YTXML556YLAFHZSTEONWXRJ23PGW7Z6SKT3BV63ZEPWDTXAC uint64_t value = solver_Algebra_parse(&a, input);printf("'%s' =? ", input);solver_Algebra_show(&a, value);solver_Algebra_free(&a);
static void assert_is_true(struct solver_Algebra *a, const char *input) {uint64_t expr = solver_Algebra_parse(a, input);if(solver_Algebra_to_boolean(a, expr) != solver_Algebra_boolean(a, true)) {printf("assert_is_true\n");printf("input: %s\n", input);printf("parsed: ");solver_Algebra_show(a, expr);fprintf(stderr, "failed\n");exit(1);}
static void test_parse(void) {echo_test("2");echo_test("2 + 2");echo_test("2 + x");}static void assert_is_true(struct solver_Algebra *a, uint64_t expr) {expr = solver_Algebra_simplify(a, expr);if(!solver_Algebra_to_boolean(a, expr)) {
static void assert_is_false(struct solver_Algebra *a, const char *input) {uint64_t expr = solver_Algebra_parse(a, input);if(solver_Algebra_to_boolean(a, expr) != solver_Algebra_boolean(a, false)) {printf("assert_is_false\n");printf("input: %s\n", input);printf("parsed: ");
static int qsort_term_compare(const void *lhs_, const void *rhs_, void *ud) {return term_compare((struct solver_Algebra *)ud, *(uint64_t *)lhs_, *(uint64_t *)rhs_);}
static bool sum_merge_single_term(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs, uint64_t *merged) {if(is_number(lhs) && is_number(rhs)) {*merged = number_add(a, lhs, rhs);return true;}// x + x -> 2xif(is_variable(lhs) && is_variable(rhs) && alias_str_same(unpack_variable(lhs), unpack_variable(rhs))) {uint64_t product_values[2] = { pack_integer(2), lhs };*merged = embed_product(a, 2, product_values);return true;}return false;}
if(count == 0) return pack_integer(0);if(count == 1) return values[0];if(count == 2) {if(is_number(values[0]) && is_number(values[1])) {return number_add(a, values[0], values[1]);
uint64_t merged;if(count == 0) {return pack_integer(0);} else if(count == 1) {return values[0];} else if(count == 2) {if(sum_merge_single_term(a, values[0], values[1], &merged)) {return merged;
// x + x -> 2xif(is_variable(values[0]) && values[0] == values[1]) {uint64_t product_values[2] = { pack_integer(2), values[0] };return embed_product(a, 2, product_values);
// break open any immediate child sums and mergeuint32_t total_count = 0;for(uint32_t i = 0; i < count; i++) {if(is_sum(values[i])) {total_count += get_list_count(values[i]);} else {total_count++;
// 2x + x -> 3x// if(is_product(values[0]) && get_count(a, values[0]) == 2 && is_number(get_index(a, values[0], 0)) && is_equal(get_index(a, values[0]
uint32_t new_count = 0;uint64_t * new_values = alias_stack_allocation(sizeof(*new_values) * total_count, alignof(*new_values));#define MERGE_INTO_NEW(TO_MERGE) do { \uint32_t k; \for(k = 0; k < new_count; k++) { \if(sum_merge_single_term(a, new_values[k], TO_MERGE, &merged)) { \new_values[k] = merged; \break; \} \} \if(k == new_count) { \new_values[new_count++] = TO_MERGE; \} \} while(0)// for each itemfor(uint32_t i = 0; i < count; i++) {if(is_sum(values[i])) {uint32_t inner_count = get_list_count(values[i]);for(uint32_t j = 0; j < inner_count; j++) {uint64_t to_merge = get_index(a, values[i], j);MERGE_INTO_NEW(to_merge);}} else {MERGE_INTO_NEW(values[i]);}
variable(O) ::= IDENTIFIER(I). { O = solver_Algebra_variable(extra.a, alias_str_format(NULL, "%.*s", I.string.end - I.string.start, I.string.start)); }
variable(O) ::= IDENTIFIER(I). { O = solver_Algebra_variable(extra.a, alias_str_clone_substring(NULL, I.string.start, I.string.end - I.string.start)); }
}}static int integer_integer_compare(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {// TODO big integer upgradereturn unpack_integer(rhs) - unpack_integer(lhs);}static int integer_compare(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {assert(is_number(rhs));switch(get_tag(rhs)) {case Tag_Integer:return integer_integer_compare(a, lhs, rhs);default:return -1;
static bool equals__real_real(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {return unpack_real(lhs) == unpack_real(rhs);}static bool equals__real(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {switch(get_tag(rhs)) {case Tag_Real:return equals__real_real(a, lhs, rhs);default:return false;}}static bool equals__variable_variable(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {return alias_str_same(unpack_variable(lhs), unpack_variable(rhs));}
#define BINARY_EQUALS(TYPE, TAG, FN) \static bool TYPE##_##TYPE##_equals(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) FN \static bool TYPE##_equals(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) { \switch(get_tag(rhs)) { \case TAG: \return TYPE##_##TYPE##_equals(a, lhs, rhs); \default: \return pack_undefined(); \} \
static bool equals__variable(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {switch(get_tag(rhs)) {case Tag_Variable:return equals__variable_variable(a, lhs, rhs);default:return false;}}static bool equals__boolean_boolean(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {return unpack_boolean(lhs) == unpack_boolean(rhs);}static bool equals__boolean(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {switch(get_tag(rhs)) {case Tag_Boolean:return equals__boolean_boolean(a, lhs, rhs);default:return false;}}static bool equals__undefined_undefined(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {unpack_undefined(lhs);unpack_undefined(rhs);return true;}static bool equals__undefined(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {switch(get_tag(rhs)) {case Tag_Undefined:return equals__undefined_undefined(a, lhs, rhs);default:return false;}}static bool equals__integer_integer(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {return unpack_integer(lhs) == unpack_integer(rhs);}static bool equals__integer(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {switch(get_tag(rhs)) {case Tag_Integer:return equals__integer_integer(a, lhs, rhs);default:return false;}}static bool equals__big_integer_big_integer(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) { return false; }static bool equals__big_integer(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {switch(get_tag(rhs)) {case Tag_BigInteger:return equals__big_integer_big_integer(a, lhs, rhs);default:return false;}}static bool equals__fraction_fraction(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) { return false; }static bool equals__fraction(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {switch(get_tag(rhs)) {case Tag_Fraction:return equals__fraction_fraction(a, lhs, rhs);default:return false;}}static bool equals__power_power(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {return equals(a, get_car(a, lhs), get_car(a, rhs)) && equals(a, get_cdr(a, lhs), get_cdr(a, rhs));}static bool equals__power(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {switch(get_tag(rhs)) {case Tag_Power:return equals__power_power(a, lhs, rhs);default:return false;}}static bool equals__sum_sum(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {uint32_t count = get_list_count(lhs);if(count != get_list_count(rhs)) {return false;}for(uint32_t i = 0; i < count; i++) {if(!equals(a, get_index(a, lhs, i), get_index(a, rhs, i))) {return false;}}return true;}static bool equals__sum(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {switch(get_tag(rhs)) {case Tag_Sum:return equals__sum_sum(a, lhs, rhs);default:return false;}}static bool equals__product_product(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {uint32_t count = get_list_count(lhs);if(count != get_list_count(rhs)) {return false;}for(uint32_t i = 0; i < count; i++) {if(!equals(a, get_index(a, lhs, i), get_index(a, rhs, i))) {return false;}}return true;
#define BINARY_PAIR_EQUALS(TYPE, TAG) \BINARY_EQUALS(TYPE, TAG, { \return equals(a, get_car(a, lhs), get_car(a, rhs)) && \equals(a, get_cdr(a, lhs), get_cdr(a, rhs)) ; \})
static bool equals__product(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {switch(get_tag(rhs)) {case Tag_Product:return equals__product_product(a, lhs, rhs);default:return false;}}
#define BINARY_LIST_EQUALS(TYPE, TAG) \BINARY_EQUALS(TYPE, TAG, { \uint32_t count = get_count(a, lhs); \if(count != get_count(a, rhs)) { \return false; \} \for(uint32_t i = 0; i < count; i++) { \if(!equals(a, get_index(a, lhs, i), get_index(a, rhs, i))) { \return false; \} \} \return true; \})
static bool equals__equals(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {switch(get_tag(rhs)) {case Tag_Equals:return equals__equals_equals(a, lhs, rhs);default:return false;}}
BINARY_EQUALS(real, Tag_Real, { return unpack_real(lhs) == unpack_real(rhs); })
static bool equals__not_equals_not_equals(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {return equals(a, get_car(a, lhs), get_car(a, rhs)) && equals(a, get_cdr(a, lhs), get_cdr(a, rhs));}
BINARY_EQUALS(variable, Tag_Variable, { return unpack_variable(lhs) == unpack_variable(rhs); })BINARY_EQUALS(boolean, Tag_Boolean, { return unpack_boolean(lhs) == unpack_boolean(rhs); })BINARY_EQUALS(undefined, Tag_Undefined, { unpack_undefined(); unpack_undefined(); return true; })BINARY_EQUALS(integer, Tag_Integer, { return unpack_integer(lhs) == unpack_integer(rhs); })BINARY_EQUALS(big_integer, Tag_BigInteger, {// TODOreturn false;})
static bool equals__less_than_less_than(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {return equals(a, get_car(a, lhs), get_car(a, rhs)) && equals(a, get_cdr(a, lhs), get_cdr(a, rhs));}
BINARY_EQUALS(fraction, Tag_Fraction, {// TODOreturn false;})
static bool equals__less_than(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {switch(get_tag(rhs)) {case Tag_LessThan:return equals__less_than_less_than(a, lhs, rhs);default:return false;}}
BINARY_PAIR_EQUALS(power, Tag_Power)BINARY_LIST_EQUALS(sum, Tag_Sum)BINARY_LIST_EQUALS(product, Tag_Sum)BINARY_PAIR_EQUALS(equals, Tag_Equals)BINARY_PAIR_EQUALS(not_equals, Tag_NotEquals)BINARY_PAIR_EQUALS(less_than, Tag_LessThan)BINARY_PAIR_EQUALS(greater_than, Tag_GreaterThan)
static bool equals__greater_than_greater_than(struct solver_Algebra *a, uint64_t lhs, uint64_t rhs) {return equals(a, get_car(a, lhs), get_car(a, rhs)) && equals(a, get_cdr(a, lhs), get_cdr(a, rhs));}
alias_str alias_str_clone_substring(alias_MemoryCB *mcb, alias_str s, uint32_t length) {uintmax_t l = strlen(s);if(l > length) {uint8_t * result = alias_memory_clone(mcb, s, length + 1, 1);result[length] = 0;return (alias_str)result;} else {return alias_str_clone(mcb, s);}}