The “general” domain wasn’t really about general variables, but meant as
a distinction from integer variables. For this reason, this commit
renames the “general” domain to “noninteger.”
Checking whether terms are arithmetic will be used not just in integer
variable detection but also in simplifying formulas with integer
variables. For this purpose, the arithmetic check is moved to a commonly
accessible header file.
This moves the commonly enum classes EvaluationResult, OperationResult,
and Tristate to the Utils header file to avoid code duplication.
Additionally, the SimplificationResult class is replaced by the
semantically similar OperationResult.
If making a variable noninteger turns the entire formula obtained from
completion true, we can drop that statement and conclude that the
variable is integer.
This reimplements integer variable detection as two parts. The first one
is a visitor class that recursively searches for all declared variables
in a formula and applies the second part, a custom functor.
Two such functors are implemented. The first one checks whether a
predicate definition is falsified by making a variable noninteger, in
which case it can be concluded that the variable in question is integer.
The second functor checks whether bound variables in a quantified
formula turn the quantified part false, again to conclude that variables
are integer.
This piece of code was responsible for propagating the domain of
predicate parameters to argument variables. However, this approach
doesn’t seem to be correct, which is why this commit removes it.
This is a reimplementation of the integer variable detection procedure.
The idea is to iteratively assume variables to be noninteger, and to
prove that this would lead to a false or erroneous result. If the proof
is successful, the variable is integer as a consequence.
With this change, domains detected for predicate parameters are properly
propagated to all occurences of the respective variables, enabling more
integer simplifications.
This adds a new syntax for declaring functions integer:
#external integer(<function name>(<arity)).
If a function is declared integer, it may enable some variables to be
detected as integer as well.
For clarity, this moves the Domain enum class to a separate header,
because it’s not just variable-specific but also applicable to
functions, for example.
This adds initial support for detecting integer variables in formulas.
The scope is somewhat limited in that variables matching predicate
parameters with known integer type aren’t propagated to be integer as
well yet. Also, the use of constants and functions prevents variables
from being detected as integer, because they have to be assumed to be
externally defined in such a way that they evaluate to general values
and not necessarily integers.
The Tristate class (representing truth values that are either true,
false, or unknown) is used at multiple ends. This moves it to a separate
header for reusing it properly.
This refactoring separates predicates from their declarations. The
purpose of this is to avoid duplicating properties specific to the
predicate declaration and not its occurrences in the program.
With this change, the domain of variable declarations can be specified.
While the default is the general domain of all precomputed value, this
adds support for integer variables, for which advanced simplification
rules apply.
cxxopts 2.1.0 has a bug preventing it from being used with standard main
signatures. This updates cxxopts to the commit after release 2.1.0,
where this issue was addressed.
The unary modulus operation does not require extra parentheses to be
printed in cases like “|X + Y|”. This adds a new option to the printing
routine to omit parentheses in cases where the parent expression already
defines a parenthesis-like scope (currently only with unary operations).