4-variable-simplifier/main.c
2025-07-01 12:15:15 -05:00

177 lines
3.6 KiB
C

#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <assert.h>
#include <debug.h>
#include <cmdln.h>
#include <print.h>
#include <evaluate.h>
#include <simplifications.h>
#include <get_cached_simplifications.h>
int main(int argc, char* const* argv)
{
ENTER;
struct cmdln_flags flags = parse_args(argc, argv);
struct simplifications* simps = get_cached_simplifications(&flags);
if (flags.print_all_and_quit)
{
for (int i = 0; i < N; i++)
{
int cost = simps->main.data[i].cost;
if (cost != INT_MAX)
{
printf("0b%016b: [%2i]: ", i, cost);
print(&flags, simps, &simps->main, i);
puts("");
}
}
}
else if (flags.print_max_operators_needed_and_quit)
{
printf("statistics:" "\n");
uintmax_t total_cost = 0;
int n = 0;
int max_cost = 0;
for (int i = 0; i < N; i++)
{
int cost = simps->main.data[i].cost;
if (cost != INT_MAX)
{
if (max_cost < cost)
{
max_cost = cost;
}
total_cost += cost;
n += 1;
}
}
if (n)
{
printf("minimum operators needed: 1" "\n");
printf("maximum operators needed: %i" "\n", max_cost);
double average = (double) total_cost / n;
printf("average operators needed: %g" "\n", average);
double working = 0.0;
for (int i = 0; i < N; i++)
{
int cost = simps->main.data[i].cost;
if (cost != INT_MAX)
{
working += pow(cost - average, 2);
}
}
double stddev = sqrt(working / (n - 1));
printf("standard deviation: %g" "\n", stddev);
}
else
{
puts("everything unreachable: no statistics to give");
}
}
else if (flags.command)
{
uint16_t truthtable = evaluate(flags.command);
if (simps->main.data[truthtable].kind == ek_unreachable)
{
puts("Unreachable");
}
else
{
printf("%2i: ", simps->main.data[truthtable].cost);
print(&flags, simps, &simps->main, truthtable);
puts("");
}
}
else
{
if (!flags.quiet)
{
puts("Use C-style syntax for boolean operators and expressions.");
puts("Available variables: 'w', 'x', 'y' and 'z'.");
puts("Extended operators: nor is '!|', orn is '|!', nand is '!&', andn is '&!'.");
puts("Comparison operators are also suppported.");
}
for (char* line; (line = readline(">>> ")); free(line))
{
if (!*line) continue;
add_history(line);
uint16_t truthtable = evaluate(line);
// printf("truthtable = 0b%016b\n", truthtable);
if (simps->main.data[truthtable].kind == ek_unreachable)
{
puts("unreachable");
}
else
{
printf("%2i: ", simps->main.data[truthtable].cost);
print(&flags, simps, &simps->main, truthtable);
puts("");
}
}
}
return 0;
}