C++ Mathematical Expression Toolkit (ExprTk) release
Loading...
Searching...
No Matches
exprtk_truthtable_gen.cpp
Go to the documentation of this file.
1/*
2 **************************************************************
3 * C++ Mathematical Expression Toolkit Library *
4 * *
5 * ExprTk Truth Table Generator *
6 * Author: Arash Partow (1999-2024) *
7 * URL: https://www.partow.net/programming/exprtk/index.html *
8 * *
9 * Copyright notice: *
10 * Free use of the Mathematical Expression Toolkit Library is *
11 * permitted under the guidelines and in accordance with the *
12 * most current version of the MIT License. *
13 * https://www.opensource.org/licenses/MIT *
14 * SPDX-License-Identifier: MIT *
15 * *
16 **************************************************************
17*/
18
19
20#include <cmath>
21#include <cstdio>
22#include <string>
23
24#include "exprtk.hpp"
25
26
27template <typename T>
28void truth_table_generator(const std::string& boolean_expression)
29{
30 typedef exprtk::symbol_table<T> symbol_table_t;
31 typedef exprtk::expression<T> expression_t;
32 typedef exprtk::parser<T> parser_t;
33 typedef exprtk::parser_error::type err_t;
34 typedef typename parser_t::settings_store settings_t;
35
36 symbol_table_t symbol_table;
37
38 expression_t expression;
39 expression.register_symbol_table(symbol_table);
40
41 static const std::size_t compile_options =
42 settings_t::e_replacer +
43 settings_t::e_joiner +
44 settings_t::e_numeric_check +
45 settings_t::e_bracket_check +
46 settings_t::e_sequence_check +
47 settings_t::e_strength_reduction +
48 settings_t::e_disable_usr_on_rsrvd;
49
50 parser_t parser(settings_t(compile_options)
51 .disable_all_base_functions ()
52 .disable_all_control_structures());
53
54 parser.enable_unknown_symbol_resolver();
55
56 parser.dec().collect_variables() = true;
57 parser.dec().collect_functions() = true;
58
59 if (!parser.compile(boolean_expression,expression))
60 {
61 printf("Error: %s\tExpression: %s\n",
62 parser.error().c_str(),
63 boolean_expression.c_str());
64
65 for (std::size_t i = 0; i < parser.error_count(); ++i)
66 {
67 err_t error = parser.get_error(i);
68
69 printf("Error: %02d Position: %02d "
70 "Type: [%s] "
71 "Message: %s "
72 "Expression: %s\n",
73 static_cast<int>(i),
74 static_cast<int>(error.token.position),
75 exprtk::parser_error::to_str(error.mode).c_str(),
76 error.diagnostic.c_str(),
77 boolean_expression.c_str());
78
79 exprtk::parser_error::update_error(error,boolean_expression);
80
81 printf("Error[%02d] at line: %d column: %d\n",
82 static_cast<int>(i),
83 static_cast<int>(error.line_no),
84 static_cast<int>(error.column_no));
85 }
86
87 return;
88 }
89
90 typedef typename parser_t::dependent_entity_collector::symbol_t dec_symbol_t;
91
92 std::deque<dec_symbol_t> symbol_list;
93
94 parser.dec().symbols(symbol_list);
95
96 if (symbol_list.empty())
97 {
98 printf("Error: No variables found to build truth table.\n");
99 return;
100 }
101
102 for (std::size_t i = 0; i < symbol_list.size(); ++i)
103 {
104 if (exprtk::details::imatch(symbol_list[i].first,"not"))
105 {
106 symbol_list.erase(symbol_list.begin() + i);
107
108 if (i >= symbol_list.size())
109 break;
110 }
111
112 if (parser_t::e_st_function == symbol_list[i].second)
113 {
114 printf("Error: call to function '%s' not allowed.\n",symbol_list[i].first.c_str());
115 return;
116 }
117 }
118
119 if (symbol_list.size() > 32)
120 {
121 printf("Error: no more than 32 unique variables allowed.\n");
122 return;
123 }
124
125 unsigned int upper_bound = 1 << symbol_list.size();
126
127 const int index_width = static_cast<int>(std::ceil(std::log10(upper_bound)));
128
129 // Print truth table header
130 printf(" #%s ",std::string(index_width - 1,' ').c_str());
131
132 for (std::size_t i = 0; i < symbol_list.size(); ++i)
133 {
134 printf("| %s ",symbol_list[i].first.c_str());
135 }
136
137 printf("| %s \n",boolean_expression.c_str());
138
139 for (std::size_t i = 0; i < upper_bound; ++i)
140 {
141 for (std::size_t j = 0; j < symbol_list.size(); ++j)
142 {
143 symbol_table.get_variable(symbol_list[j].first)->ref() = T((i & (1 << (symbol_list.size() - j - 1))) ? 0 : 1);
144 }
145
146 const std::size_t result = static_cast<std::size_t>(expression.value());
147
148 printf(" %*d ", index_width, static_cast<int>(i));
149
150 for (std::size_t j = 0; j < symbol_list.size(); ++j)
151 {
152 printf("| %d ",static_cast<int>(symbol_table.get_variable(symbol_list[j].first)->value()));
153 }
154
155 printf("| %d \n", static_cast<int>(result));
156 }
157}
158
159int main(int argc, char* argv[])
160{
161 if (2 != argc)
162 {
163 printf("usage: exprtk_truthtable_gen <expression>\n");
164 return 1;
165 }
166
167 truth_table_generator<double>(argv[1]);
168
169 return 0;
170}
171
172/*
173 Examples:
174 ./exprtk_truthtable_gen 'A and B or C or not(D)'
175 ./exprtk_truthtable_gen '(A and not(B)) nor not(C xor D)'
176 ./exprtk_truthtable_gen '(A nand not(B or C)) xor not(D xor E)'
177*/
void truth_table_generator(const std::string &boolean_expression)
bool imatch(const char_t c1, const char_t c2)
Definition exprtk.hpp:190
bool update_error(type &error, const std::string &expression)
Definition exprtk.hpp:22114
std::string to_str(error_mode mode)
Definition exprtk.hpp:22098