Original CVC5 README file: https://github.com/cvc5/cvc5/blob/main/README.md
cvc5 is a tool for determining the satisfiability of a first order formula modulo a first order theory (or a combination of such theories). It is the fifth in the Cooperating Validity Checker family of tools (CVC, CVC Lite, CVC3, CVC4) but does not directly incorporate code from any previous version prior to CVC4.
This project expands CVC5 by adding the --solve-int-as-bag option. This option introduces a preprocessing pass that transforms any assertions involving integers into assertions involving bags (multi-sets). As a result, multiplication is interpreted as the union disjoint of bags instead of the multiplication of integers. The equivalent bag representation of an integer is based on its prime factorization. Since this approach only deals with positive integers (which have unique prime factorizations), integers are mapped to natural numbers. For example, the bag (0, 2) represents the number 2^2=4.
Define the function
This mapping ensures that all results are within the set
Define the inverse function
- For
$z = 3$ :$g(3) = 2 \times 3 + 2 = \textbf{8}$ - For
$z = -3$ :$g(-3) = -2 \times (-3) + 1 = \textbf{7}$ - For
$n = 8$ :$g^{-1}(8) = \frac{8}{2} - 1 = \textbf{3}$ - For
$n = 7$ :$g^{-1}(7) = -\frac{7 - 1}{2} = \textbf{-3}$
In addition to this transformation, new operators have been implemented based on this idea:
- gcd (greatest common divisor)
- lcm (least common multiple)
- is_prime (checks if a number is prime)
- factors (lists the prime factors of a number)
- num_of_factors (counts the number of different prime factors of a number)
The supported integer operators are translated to equivalent bag operators, with each integer first converted to its bag representation as described:
- integer multiplication – translated to the union of disjoint bags.
- gcd – represented as the intersection of bags, where the multiplicity of each element is the minimum of its multiplicities in the two bags.
- lcm – represented as the union of bags, where the multiplicity of each element is the maximum of its multiplicities.
- is_prime – the bag's cardinality equals 1 (i.e., the bag contains only one distinct element).
- factors – the set of distinct bag elements.
- num_of_factors – the cardinality of the set of distinct bag elements.
-
Build CVC5: Follow the standard CVC5 build instructions from here.
-
Running an Example: To run CVC5 on the
evaluation/multiplication/equals/test-result1-10.smt2
file, use the command:./build/bin/cvc5 evaluation/multiplication/equals/test-result1-10.smt2
-
Using the New Feature: To enable the new integer-to-bag transformation feature (and the other operators), add the
--solve-int-as-bag
flag:./build/bin/cvc5 evaluation/multiplication/equals/test-result1-10.smt2 --solve-int-as-bag
-
Dumping Models: If you wish to see the models for satisfiable (SAT) tests, include the
--dump-models
flag as follows:./build/bin/cvc5 evaluation/multiplication/equals/test-result1-10.smt2 --solve-int-as-bag --dump-models
We compared the performance of CVC5 with and without our preprocessing pass. All tests included either multiplication or the newly implemented operators. For the new operators, we created equivalent tests without using them directly, since CVC5 does not natively support these operators without our option. We ran CVC5 three times for each test: first without any additional options, then with the --cegqi-all --nl-ext-tplanes flags (which enable more efficient arithmetic solving in CVC5), and finally with our new feature enabled.
All tests are organized into the following subfolders within the "evaluation" folder:
- multiplication: Contains various tests involving multiplication.
- operators: Contains tests for the new operators in two forms:
- original: Using the new operators.
- primitive: Using pure CVC5 logic without the new operators.
- randomTests: Contains randomly generated tests that involve only multiplication. Each folder includes Python scripts for generating tests and Bash scripts for comparing the results.
Tests were executed on a large cluster, and a detailed comparison of the results can be found in the "tests_results_on_cluster.txt" file.
A total review of the results is:
Test Configuration | Status | Total | Solved | SAT | UNSAT | Best | Timeout | Error | Uniq | Time (CPU) | Memory (MB) |
---|---|---|---|---|---|---|---|---|---|---|---|
No Bags (no flags) | OK | 1110 | 353 | 294 | 59 | 111 | 739 | 1 | 0 | 7970.7 | 15913.3 |
No Bags (--cegqi-all --nl-ext-tplanes flags) | OK | 1110 | 354 | 294 | 60 | 227 | 755 | 1 | 0 | 8037.1 | 15285.2 |
With Bags (new feature, --solve-int-as-bag flag) | OK | 1110 | 895 | 603 | 292 | 810 | 220 | 0 | 541 | 4210.9 | 22058.7 |
The results indicate a significant performance advantage for our preprocessing pass in both multiplication and operator tests.
- Evaluation folder: Contains all test cases and results.
- src/preprocessing/passes/int_to_bag.cpp(h): Contains the code for the new preprocessing pass and the new operators conversion to bag operators.
- src/theory/bags/bags_utils.cpp(h): Modified to include the mapping between integers and natural numbers (excluding 1), and the implementation of bag.to.int and int.to.bag operators, which convert bags to integers based on prime factorization and vice versa.
- Other Files: Minor changes were made to various files to add new operator kinds and integrate them into the existing framework.
All changes in this fork were made by Yehonatan Calinsky and Yoni Zohar.