NilFoundation / zkLLVM

Zero-Knowledge Proof Systems Circuit Compiler
https://docs.nil.foundation/zkllvm
274 stars 46 forks source link

[Feature request]: Use .size() of std::array as a constant #536

Open ETatuzova opened 5 months ago

ETatuzova commented 5 months ago

We cannot interpret .size() of std::array as a constant (for example as a number of for-loop iterations). But it in fact it is a constant. I understand, we can create some named constant instead of size().

Small example:

#include <nil/crypto3/algebra/curves/pallas.hpp>

constexpr std::array<std::size_t, 5> sizes = {1,2,3,4,5};

using namespace nil::crypto3::algebra::curves;

[[circuit]] typename pallas::base_field_type::value_type
    field_arithmetic_example(typename pallas::base_field_type::value_type a,
                             typename pallas::base_field_type::value_type b) {

    for( std::size_t i = 0; i < sizes.size(); i++ ){
        a = a + b;
    }
    return a;
}
akokoshn commented 5 months ago

std::array::size() is constexpr but not static and no known at compile time. Can use expression based on type: std::tuple_size<decltype(c)>::value. But most user friendly way - define constexpr value and use it for std::array definitions and loops:

constexpr size = 5;
constexpr std::array<std::size_t, size> sizes = {1,2,3,4,5};

[[circuit]] typename pallas::base_field_type::value_type
    field_arithmetic_example(typename pallas::base_field_type::value_type a,
                             typename pallas::base_field_type::value_type b) {

    for( std::size_t i = 0; i < size; i++ ){
        a = a + b;
    }
    return a;
}

const expr size = sizes.size() also works, for example:

[[circuit]] typename pallas::base_field_type::value_type
    field_arithmetic_example(std::array<int, 5> arr,
                                             typename pallas::base_field_type::value_type a,
                                             typename pallas::base_field_type::value_type b) {

    constexpr size = arr.size();
    for( std::size_t i = 0; i < size; i++ ){
        a = a + b;
    }
    return a;
}