diff options
author | Aina Niemetz <aina.niemetz@gmail.com> | 2017-11-09 04:47:02 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-09 04:47:02 -0800 |
commit | a9cf481470c324a04f2254c5745eee26c45cb309 (patch) | |
tree | ad9065cae3e2728b41becc51697955e2ce8b26c1 /src/util/integer_cln_imp.cpp | |
parent | 9444927c027e96f0fce22398611b97c274eff6b3 (diff) |
Add modular arithmetic operators. (#1321)
This adds functions on Integers to compute modular addition, multiplication and inverse.
This is required for the Gaussian Elimination preprocessing pass for BV.
Diffstat (limited to 'src/util/integer_cln_imp.cpp')
-rw-r--r-- | src/util/integer_cln_imp.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/util/integer_cln_imp.cpp b/src/util/integer_cln_imp.cpp index b09d2429c..8f98d908f 100644 --- a/src/util/integer_cln_imp.cpp +++ b/src/util/integer_cln_imp.cpp @@ -155,4 +155,36 @@ Integer Integer::pow(unsigned long int exp) const { } } +Integer Integer::modAdd(const Integer& y, const Integer& m) const +{ + cln::cl_modint_ring ry = cln::find_modint_ring(m.d_value); + cln::cl_MI xm = ry->canonhom(d_value); + cln::cl_MI ym = ry->canonhom(y.d_value); + cln::cl_MI res = xm + ym; + return Integer(ry->retract(res)); +} + +Integer Integer::modMultiply(const Integer& y, const Integer& m) const +{ + cln::cl_modint_ring ry = cln::find_modint_ring(m.d_value); + cln::cl_MI xm = ry->canonhom(d_value); + cln::cl_MI ym = ry->canonhom(y.d_value); + cln::cl_MI res = xm * ym; + return Integer(ry->retract(res)); +} + +Integer Integer::modInverse(const Integer& m) const +{ + PrettyCheckArgument(m > 0, m, "m must be greater than zero"); + cln::cl_modint_ring ry = cln::find_modint_ring(m.d_value); + cln::cl_MI xm = ry->canonhom(d_value); + /* normalize to modulo m for coprime check */ + cln::cl_I x = ry->retract(xm); + if (x == 0 || cln::gcd(x, m.d_value) != 1) + { + return Integer(-1); + } + cln::cl_MI res = cln::recip(xm); + return Integer(ry->retract(res)); +} } /* namespace CVC4 */ |