• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "util/bit_vector.h"
17 #include "util/set_operations.h"
18 #include "util/range.h"
19 #include "util/lazy.h"
20 
21 #include <gtest/gtest.h>
22 #include <rapidcheck/gtest.h>
23 #include "util/tests/environment.h"
24 
25 #include <cstdint>
26 #include <initializer_list>
27 #include <string>
28 #include <set>
29 
30 // NOLINTNEXTLINE(google-build-using-namespace)
31 using namespace ark::verifier;
32 
33 using StdSet = std::set<size_t>;
34 
35 struct BSet {
36     // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
37     StdSet indices;
38     // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
39     BitVector bits;
40 
IsEqualBSet41     bool IsEqual() const
42     {
43         if (bits.SetBitsCount() != indices.size()) {
44             return false;
45         }
46         for (const auto &elem : indices) {
47             if (!bits[elem]) {
48                 return false;
49             }
50         }
51         return true;
52     }
53 };
54 
55 namespace rc {
56 
57 constexpr size_t MAX_VALUE = 1024U;
58 // NOLINTNEXTLINE(cert-err58-cpp)
59 auto g_valueGen = gen::inRange<size_t>(0, MAX_VALUE);
60 
61 template <>
62 struct Arbitrary<BSet> {
arbitraryrc::Arbitrary63     static Gen<BSet> arbitrary()  // NOLINT(readability-identifier-naming)
64     {
65         // NOLINTNEXTLINE(readability-magic-numbers)
66         auto setNInc = gen::pair(gen::container<std::set<size_t>>(g_valueGen), gen::inRange(1, 100));  // N = 100
67         return gen::map(setNInc, [](auto paramSetNInc) {
68             auto &[set, inc] = paramSetNInc;
69             size_t size = (set.empty() ? 0 : *set.rbegin()) + inc;
70             BitVector bits {size};
71             for (const auto &idx : set) {
72                 bits[idx] = 1;
73             }
74             return BSet {set, bits};
75         });
76     }
77 };
78 
79 template <>
80 struct Arbitrary<Range<size_t>> {
arbitraryrc::Arbitrary81     static Gen<Range<size_t>> arbitrary()  // NOLINT(readability-identifier-naming)
82     {
83         return gen::map(gen::pair(g_valueGen, g_valueGen), [](auto pair) {
84             return Range<size_t> {std::min(pair.first, pair.second), std::max(pair.first, pair.second)};
85         });
86     }
87 };
88 
89 }  // namespace rc
90 
91 namespace ark::verifier::test {
92 
93 // NOLINTNEXTLINE(google-build-using-namespace)
94 using namespace rc;
95 
96 using Interval = ark::verifier::Range<size_t>;
97 using Intervals = std::initializer_list<Interval>;
98 
ClassifySize(const std::string & name,size_t size,const Intervals & intervals)99 void ClassifySize(const std::string &name, size_t size, const Intervals &intervals)
100 {
101     for (const auto &i : intervals) {
102         RC_CLASSIFY(i.Contains(size), name + " " + std::to_string(i));
103     }
104 }
105 
106 // NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp)
107 const EnvOptions OPTIONS {"VERIFIER_TEST"};
108 // NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp,readability-magic-numbers)
109 Intervals g_statIntervals = {{0, 10U}, {11U, 50U}, {51U, 100U}, {101U, MAX_VALUE}};
110 
Stat(const BSet & bitset)111 void Stat(const BSet &bitset)
112 {
113     if (OPTIONS.Get<bool>("verbose", false)) {
114         ClassifySize("Bits.size() in", bitset.bits.Size(), g_statIntervals);
115         ClassifySize("Indices.size() in", bitset.indices.size(), g_statIntervals);
116     }
117 }
118 
Universum(size_t size)119 StdSet Universum(size_t size)
120 {
121     return ToSet<StdSet>(Interval(0, size - 1));
122 }
123 
124 RC_GTEST_PROP(TestBitvector, BasicTestSetBitsCount, (const BSet &bit_set))
125 {
126     Stat(bit_set);
127     RC_ASSERT(bit_set.bits.SetBitsCount() == bit_set.indices.size());
128 }
129 
130 RC_GTEST_PROP(TestBitvector, BasicTestOperatorEq, (const BSet &bit_set))
131 {
132     Stat(bit_set);
133     auto bits = bit_set.bits;
134     RC_ASSERT(bits.Size() == bit_set.bits.Size());
135     for (size_t idx = 0; idx < bits.Size(); ++idx) {
136         RC_ASSERT(bits[idx] == bit_set.bits[idx]);
137     }
138     RC_ASSERT(bits.SetBitsCount() == bit_set.bits.SetBitsCount());
139 }
140 
141 RC_GTEST_PROP(TestBitvector, BasicTestClr, (BSet && bset))
142 {
143     Stat(bset);
144     bset.bits.Clr();
145     RC_ASSERT(bset.bits.SetBitsCount() == 0U);
146 }
147 
148 RC_GTEST_PROP(TestBitvector, BasicTestSet, (BSet && bset))
149 {
150     Stat(bset);
151     bset.bits.Set();
152     RC_ASSERT(bset.bits.SetBitsCount() == bset.bits.Size());
153 }
154 
155 RC_GTEST_PROP(TestBitvector, BasicTestInvert, (BSet && bset))
156 {
157     Stat(bset);
158     auto zeroBits = bset.bits.Size() - bset.bits.SetBitsCount();
159     bset.bits.Invert();
160     RC_ASSERT(bset.bits.SetBitsCount() == zeroBits);
161 }
162 
163 RC_GTEST_PROP(TestBitvector, BasicTestClrIdx, (BSet && bset, std::set<size_t> &&indices))
164 {
165     Stat(bset);
166     auto size = bset.bits.Size();
167     for (const auto &idx : indices) {
168         bset.bits.Clr(idx % size);
169         bset.indices.erase(idx % size);
170     }
171     RC_ASSERT(bset.bits.SetBitsCount() == bset.indices.size());
172 }
173 
174 RC_GTEST_PROP(TestBitvector, BasicTestSetIdx, (BSet && bset, std::set<size_t> &&indices))
175 {
176     Stat(bset);
177     auto size = bset.bits.Size();
178     for (const auto &idx : indices) {
179         auto i = idx % size;
180         bset.bits.Set(i);
181         bset.indices.insert(i);
182     }
183     RC_ASSERT(bset.bits.SetBitsCount() == bset.indices.size());
184 }
185 
186 RC_GTEST_PROP(TestBitvector, BasicTestInvertIdx, (BSet && bset, std::set<size_t> &&indices))
187 {
188     Stat(bset);
189     auto size = bset.bits.Size();
190     for (const auto &idx : indices) {
191         auto i = idx % size;
192         bset.bits.Invert(i);
193         if (bset.indices.count(i) > 0) {
194             bset.indices.erase(i);
195         } else {
196             bset.indices.insert(i);
197         }
198     }
199     RC_ASSERT(bset.bits.SetBitsCount() == bset.indices.size());
200 }
201 
202 RC_GTEST_PROP(TestBitvector, BasicTestClrFromTo, (BSet && bset, Interval &&interval))
203 {
204     RC_PRE(interval.Finish() < bset.bits.Size());
205     Stat(bset);
206     bset.bits.Clr(interval.Start(), interval.Finish());
207     for (auto idx : interval) {
208         bset.indices.erase(idx);
209     }
210     RC_ASSERT(bset.bits.SetBitsCount() == bset.indices.size());
211 }
212 
213 RC_GTEST_PROP(TestBitvector, BasicTestSetFromTo, (BSet && bset, Interval &&interval))
214 {
215     RC_PRE(interval.Finish() < bset.bits.Size());
216     Stat(bset);
217     bset.bits.Set(interval.Start(), interval.Finish());
218     for (auto idx : interval) {
219         bset.indices.insert(idx);
220     }
221     RC_ASSERT(bset.bits.SetBitsCount() == bset.indices.size());
222 }
223 
224 RC_GTEST_PROP(TestBitvector, BasicTestInvertFromTo, (BSet && bset, Interval &&interval))
225 {
226     RC_PRE(interval.Finish() < bset.bits.Size());
227     Stat(bset);
228     bset.bits.Invert(interval.Start(), interval.Finish());
229     for (auto idx : interval) {
230         if (bset.indices.count(idx) > 0) {
231             bset.indices.erase(idx);
232         } else {
233             bset.indices.insert(idx);
234         }
235     }
236     RC_ASSERT(bset.bits.SetBitsCount() == bset.indices.size());
237 }
238 
239 RC_GTEST_PROP(TestBitvector, BasicTestOperatorBitwise, (BSet && lhs, BSet &&rhs))
240 {
241     Stat(rhs);
242     Stat(lhs);
243     lhs.bits &= rhs.bits;
244     lhs.indices = SetIntersection(lhs.indices, rhs.indices);
245     RC_ASSERT(lhs.IsEqual());
246 }
247 
248 RC_GTEST_PROP(TestBitvector, BasicTestOperatorOr, (BSet && lhs, BSet &&rhs))
249 {
250     Stat(rhs);
251     Stat(lhs);
252     StdSet universum = Universum(std::max(lhs.bits.Size(), rhs.bits.Size()));
253     StdSet clamped = SetIntersection(rhs.indices, universum);
254     lhs.bits |= rhs.bits;
255     lhs.indices = SetUnion(lhs.indices, clamped);
256     RC_ASSERT(lhs.IsEqual());
257 }
258 
259 RC_GTEST_PROP(TestBitvector, BasicTestOperatorXor, (BSet && lhs, BSet &&rhs))
260 {
261     Stat(rhs);
262     Stat(lhs);
263     lhs.bits ^= rhs.bits;
264     lhs.indices = SetDifference(SetUnion(lhs.indices, rhs.indices), SetIntersection(lhs.indices, rhs.indices));
265     RC_ASSERT(lhs.IsEqual());
266 }
267 
268 RC_GTEST_PROP(TestBitvector, BasicTestResise, (BSet && bset, size_t new_size))
269 {
270     Stat(bset);
271     new_size %= bset.bits.Size();
272     bset.bits.Resize(new_size);
273     auto universum = Universum(new_size);
274     bset.indices = SetIntersection(universum, bset.indices);
275     RC_ASSERT(bset.bits.SetBitsCount() == bset.indices.size());
276     RC_ASSERT(bset.bits.Size() == new_size);
277 }
278 
279 RC_GTEST_PROP(TestBitvector, IteratorForAllIdxVal, (BSet && bset))
280 {
281     Stat(bset);
282     StdSet selected;
__anonb76ffb930302(auto idx, auto val) 283     auto handler = [&selected](auto idx, auto val) {
284         while (val) {
285             if (val & 1U) {
286                 selected.insert(idx);
287             }
288             val >>= 1U;
289             ++idx;
290         }
291         return true;
292     };
293     bset.bits.ForAllIdxVal(handler);
294     RC_ASSERT(selected == bset.indices);
295 }
296 
297 RC_GTEST_PROP(TestBitvector, IteratorForAllIdxOf1, (BSet && bset))
298 {
299     Stat(bset);
300     StdSet result;
__anonb76ffb930402(auto idx) 301     bset.bits.ForAllIdxOf<1>([&result](auto idx) {
302         result.insert(idx);
303         return true;
304     });
305     RC_ASSERT(result == bset.indices);
306 }
307 
308 RC_GTEST_PROP(TestBitvector, IteratorForAllIdxOf0, (BSet && bset))
309 {
310     Stat(bset);
311     StdSet result;
__anonb76ffb930502(auto idx) 312     bset.bits.ForAllIdxOf<0>([&result](auto idx) {
313         result.insert(idx);
314         return true;
315     });
316     StdSet universum = Universum(bset.bits.Size());
317     RC_ASSERT(result == SetDifference(universum, bset.indices));
318 }
319 
320 RC_GTEST_PROP(TestBitvector, LazyIteratorsLazyIndicesOf1, (BSet && bset))
321 {
322     Stat(bset);
323     size_t from = *gen::inRange<size_t>(0, bset.bits.Size() - 1);
324     size_t to =
325         *gen::oneOf(gen::inRange<size_t>(from, bset.bits.Size()), gen::just(std::numeric_limits<size_t>::max()));
326     auto result = ContainerOf<StdSet>(bset.bits.LazyIndicesOf<1>(from, to));
327     StdSet expected = bset.indices;
328     if (from > 0) {
329         expected.erase(expected.begin(), expected.lower_bound(from));
330     }
331     if (!expected.empty() && to < *expected.rbegin()) {
332         expected.erase(expected.upper_bound(to), expected.end());
333     }
334     RC_ASSERT(result == expected);
335 }
336 
337 RC_GTEST_PROP(TestBitvector, LazyIteratorsLazyIndicesOf0, (BSet && bset))
338 {
339     Stat(bset);
340     size_t from = *gen::inRange<size_t>(0, bset.bits.Size() - 1);
341     auto result = ContainerOf<StdSet>(bset.bits.LazyIndicesOf<0>(from));
342     StdSet universum = Universum(bset.bits.Size());
343     StdSet expected = SetDifference(universum, bset.indices);
344     if (from > 0) {
345         expected.erase(expected.begin(), expected.lower_bound(from));
346     }
347     RC_ASSERT(result == expected);
348 }
349 
350 RC_GTEST_PROP(TestBitvector, PowerOfFoldedBitsetsAnd2Arg, (BSet && bset1, BSet &&bset2))
351 {
352     Stat(bset1);
353     Stat(bset2);
354     auto result = BitVector::PowerOfAnd(bset1.bits, bset2.bits);
355     RC_ASSERT(result == SetIntersection(bset1.indices, bset2.indices).size());
356 }
357 
358 RC_GTEST_PROP(TestBitvector, PowerOfFoldedBitsetsAnd3Arg, (BSet && bset1, BSet &&bset2, BSet &&bset3))
359 {
360     Stat(bset1);
361     Stat(bset2);
362     Stat(bset3);
363     auto result = BitVector::PowerOfAnd(bset1.bits, bset2.bits, bset3.bits);
364     RC_ASSERT(result == SetIntersection(bset1.indices, bset2.indices, bset3.indices).size());
365 }
366 
367 RC_GTEST_PROP(TestBitvector, PowerOfFoldedBitsetsOr2Arg, (BSet && bset1, BSet &&bset2))
368 {
369     Stat(bset1);
370     Stat(bset2);
371     auto result = BitVector::PowerOfOr(bset1.bits, bset2.bits);
372     auto size = std::min(bset1.bits.Size(), bset2.bits.Size());
373     auto universum = Universum(size);
374     RC_ASSERT(result == SetIntersection(universum, SetUnion(bset1.indices, bset2.indices)).size());
375 }
376 
377 RC_GTEST_PROP(TestBitvector, PowerOfFoldedBitsetsOr3Arg, (BSet && bset1, BSet &&bset2, BSet &&bset3))
378 {
379     Stat(bset1);
380     Stat(bset2);
381     Stat(bset3);
382     auto result = BitVector::PowerOfOr(bset1.bits, bset2.bits, bset3.bits);
383     auto size = std::min(std::min(bset1.bits.Size(), bset2.bits.Size()), bset3.bits.Size());
384     auto universum = Universum(size);
385     RC_ASSERT(result == SetIntersection(universum, SetUnion(bset1.indices, bset2.indices, bset3.indices)).size());
386 }
387 
388 RC_GTEST_PROP(TestBitvector, PowerOfFoldedBitsetsXor2Arg, (BSet && bset1, BSet &&bset2))
389 {
390     Stat(bset1);
391     Stat(bset2);
392     auto result = BitVector::PowerOfXor(bset1.bits, bset2.bits);
393     auto size = std::min(bset1.bits.Size(), bset2.bits.Size());
394     auto universum = Universum(size);
395     auto setResult = SetIntersection(universum, SetDifference(SetUnion(bset1.indices, bset2.indices),
396                                                               SetIntersection(bset1.indices, bset2.indices)));
397     RC_ASSERT(result == setResult.size());
398 }
399 
400 RC_GTEST_PROP(TestBitvector, PowerOfFoldedBitsetsXor3Arg, (BSet && bset1, BSet &&bset2, BSet &&bset3))
401 {
402     Stat(bset1);
403     Stat(bset2);
404     Stat(bset3);
405     auto result = BitVector::PowerOfXor(bset1.bits, bset2.bits, bset3.bits);
406     auto size = std::min(std::min(bset1.bits.Size(), bset2.bits.Size()), bset3.bits.Size());
407     auto universum = Universum(size);
408     auto xor1 = SetDifference(SetUnion(bset1.indices, bset2.indices), SetIntersection(bset1.indices, bset2.indices));
409     auto xor2 = SetDifference(SetUnion(xor1, bset3.indices), SetIntersection(xor1, bset3.indices));
410     auto setResult = SetIntersection(universum, xor2);
411     RC_ASSERT(result == setResult.size());
412 }
413 
414 RC_GTEST_PROP(TestBitvector, PowerOfFoldedBitsetsNot2Arg, (BSet && bset1, BSet &&bset2))
415 {
416     Stat(bset1);
417     Stat(bset2);
418     auto result = BitVector::PowerOfAndNot(bset1.bits, bset2.bits);
419     auto size = std::min(bset1.bits.Size(), bset2.bits.Size());
420     auto universum = Universum(size);
421     auto setResult = SetIntersection(universum, SetDifference(bset1.indices, bset2.indices));
422     RC_ASSERT(result == setResult.size());
423 }
424 
425 RC_GTEST_PROP(TestBitvector, LazyIteratorsOverFoldedBitsetsAnd1, (BSet && bset1, BSet &&bset2, BSet &&bset3))
426 {
427     Stat(bset1);
428     Stat(bset2);
429     Stat(bset3);
430     auto result = ContainerOf<StdSet>(BitVector::LazyAndThenIndicesOf<1>(bset1.bits, bset2.bits, bset3.bits));
431     auto size = std::min(std::min(bset1.bits.Size(), bset2.bits.Size()), bset3.bits.Size());
432     auto universum = Universum(size);
433     auto setResult = SetIntersection(universum, bset1.indices, bset2.indices, bset3.indices);
434     RC_ASSERT(result == setResult);
435 }
436 
437 RC_GTEST_PROP(TestBitvector, LazyIteratorsOverFoldedBitsetsAnd0, (BSet && bset1, BSet &&bset2, BSet &&bset3))
438 {
439     Stat(bset1);
440     Stat(bset2);
441     Stat(bset3);
442     auto result = ContainerOf<StdSet>(BitVector::LazyAndThenIndicesOf<0>(bset1.bits, bset2.bits, bset3.bits));
443     auto size = std::min(std::min(bset1.bits.Size(), bset2.bits.Size()), bset3.bits.Size());
444     auto universum = Universum(size);
445     auto setResult = SetDifference(universum, SetIntersection(bset1.indices, bset2.indices, bset3.indices));
446     RC_ASSERT(result == setResult);
447 }
448 
449 RC_GTEST_PROP(TestBitvector, LazyIteratorsOverFoldedBitsetsOr1, (BSet && bset1, BSet &&bset2, BSet &&bset3))
450 {
451     Stat(bset1);
452     Stat(bset2);
453     Stat(bset3);
454     auto result = ContainerOf<StdSet>(BitVector::LazyOrThenIndicesOf<1>(bset1.bits, bset2.bits, bset3.bits));
455     auto size = std::min(std::min(bset1.bits.Size(), bset2.bits.Size()), bset3.bits.Size());
456     auto universum = Universum(size);
457     auto setResult = SetIntersection(universum, SetUnion(bset1.indices, bset2.indices, bset3.indices));
458     RC_ASSERT(result == setResult);
459 }
460 
461 RC_GTEST_PROP(TestBitvector, LazyIteratorsOverFoldedBitsetsOr0, (BSet && bset1, BSet &&bset2, BSet &&bset3))
462 {
463     Stat(bset1);
464     Stat(bset2);
465     Stat(bset3);
466     auto result = ContainerOf<StdSet>(BitVector::LazyOrThenIndicesOf<0>(bset1.bits, bset2.bits, bset3.bits));
467     auto size = std::min(std::min(bset1.bits.Size(), bset2.bits.Size()), bset3.bits.Size());
468     auto universum = Universum(size);
469     auto setResult = SetDifference(universum, SetUnion(bset1.indices, bset2.indices, bset3.indices));
470     RC_ASSERT(result == setResult);
471 }
472 
473 RC_GTEST_PROP(TestBitvector, LazyIteratorsOverFoldedBitsetsXor1, (BSet && bset1, BSet &&bset2, BSet &&bset3))
474 {
475     Stat(bset1);
476     Stat(bset2);
477     Stat(bset3);
478     auto result = ContainerOf<StdSet>(BitVector::LazyXorThenIndicesOf<1>(bset1.bits, bset2.bits, bset3.bits));
479     auto size = std::min(std::min(bset1.bits.Size(), bset2.bits.Size()), bset3.bits.Size());
480     auto universum = Universum(size);
481     auto xor1 = SetDifference(SetUnion(bset1.indices, bset2.indices), SetIntersection(bset1.indices, bset2.indices));
482     auto xor2 = SetDifference(SetUnion(xor1, bset3.indices), SetIntersection(xor1, bset3.indices));
483     auto setResult = SetIntersection(universum, xor2);
484     RC_ASSERT(result == setResult);
485 }
486 
487 RC_GTEST_PROP(TestBitvector, LazyIteratorsOverFoldedBitsetsXor0, (BSet && bset1, BSet &&bset2, BSet &&bset3))
488 {
489     Stat(bset1);
490     Stat(bset2);
491     Stat(bset3);
492     auto result = ContainerOf<StdSet>(BitVector::LazyXorThenIndicesOf<0>(bset1.bits, bset2.bits, bset3.bits));
493     auto size = std::min(std::min(bset1.bits.Size(), bset2.bits.Size()), bset3.bits.Size());
494     auto universum = Universum(size);
495     auto xor1 = SetDifference(SetUnion(bset1.indices, bset2.indices), SetIntersection(bset1.indices, bset2.indices));
496     auto xor2 = SetDifference(SetUnion(xor1, bset3.indices), SetIntersection(xor1, bset3.indices));
497     auto setResult = SetDifference(universum, xor2);
498     RC_ASSERT(result == setResult);
499 }
500 
501 RC_GTEST_PROP(TestBitvector, LazyIteratorsOverFoldedBitsetsNot1, (BSet && bset1, BSet &&bset2, BSet &&bset3))
502 {
503     Stat(bset1);
504     Stat(bset2);
505     Stat(bset3);
506     auto result = ContainerOf<StdSet>(BitVector::LazyAndNotThenIndicesOf<1>(bset1.bits, bset2.bits, bset3.bits));
507     auto size = std::min(std::min(bset1.bits.Size(), bset2.bits.Size()), bset3.bits.Size());
508     auto universum = Universum(size);
509     auto setAnd = SetIntersection(bset1.indices, bset2.indices);
510     auto setNot = SetDifference(universum, bset3.indices);
511     auto setResult = SetIntersection(setAnd, setNot);
512     RC_ASSERT(result == setResult);
513 }
514 
515 RC_GTEST_PROP(TestBitvector, LazyIteratorsOverFoldedBitsetsNot0, (BSet && bset1, BSet &&bset2, BSet &&bset3))
516 {
517     Stat(bset1);
518     Stat(bset2);
519     Stat(bset3);
520     auto result = ContainerOf<StdSet>(BitVector::LazyAndNotThenIndicesOf<0>(bset1.bits, bset2.bits, bset3.bits));
521     auto size = std::min(std::min(bset1.bits.Size(), bset2.bits.Size()), bset3.bits.Size());
522     auto universum = Universum(size);
523     auto setAnd = SetIntersection(bset1.indices, bset2.indices);
524     auto setNot = SetDifference(universum, bset3.indices);
525     auto setResult = SetDifference(universum, SetIntersection(setAnd, setNot));
526     RC_ASSERT(result == setResult);
527 }
528 
529 }  // namespace ark::verifier::test
530