kmyk-jikka / Jikka

an automated solver for problems of competitive programming
https://kmyk-jikka.github.io/Jikka/playground
Apache License 2.0
152 stars 11 forks source link

copy を move に直す際にやりすぎてる #154

Closed kmyk closed 2 years ago

kmyk commented 2 years ago

MoveSemantics.hs が以下のような C++ について

int func(vector<int> a) {
    vector<int> b = a;
    b.push_back(10);
    vector<int> c = b;
    c.push_back(10);
    return b.size() + c.size();
}

これを間違えて

int func(vector<int> a) {
    a.push_back(10);
    a.push_back(10);
    return a.size() + a.size();
}

に変換してるぽい

Originally posted by @kmyk in https://github.com/kmyk/Jikka/issues/153#issuecomment-893423374

kmyk commented 2 years ago

push_back が変数を更新することを考慮してないのが原因ぽい

riantkb commented 2 years ago

153 #165

新しい issue を立てるつもりでしたがここの話と同じような気がしてきたのでここに書きます。

def f(n: int) -> int:
    a = 0
    b = 1
    for _ in range(n):
        c = (a + b) % 1000000007
        a = b
        b = c
    return a

def solve(n: int) -> int:
    return f(n)

上記のコードを変換した際に、MoveSemanticsコメントアウトした 状態だと

// ...
int64_t solve(int64_t n_0) {
    int64_t x1_4 = 1;
    int64_t x1_5 = 0;
    for (int32_t i2 = 0; i2 < int32_t(n_0); ++ i2) {
        int64_t x6 = jikka::mod::plus(jikka::modmat::floormod<2>(std::array<int64_t, 2>{x1_4, x1_5}, 1000000007)[1], jikka::modmat::floormod<2>(std::array<int64_t, 2>{x1_4, x1_5}, 1000000007)[0], 1000000007);
        int64_t x7 = x1_4;
        x1_4 = x6;
        x1_5 = x7;
    }
    return x1_5;
}
// ...

と正しいコードが得られるのに対し、 コメントアウトしていない 状態だと

// ...
int64_t solve(int64_t n_0) {
    int64_t x1_4 = 1;
    int64_t x1_5 = 0;
    for (int32_t i2 = 0; i2 < int32_t(n_0); ++ i2) {
        int64_t x6 = jikka::mod::plus(jikka::modmat::floormod<2>(std::array<int64_t, 2>{x1_4, x1_5}, 1000000007)[1], jikka::modmat::floormod<2>(std::array<int64_t, 2>{x1_4, x1_5}, 1000000007)[0], 1000000007);
        x1_4 = x6;
        x1_5 = x1_4;
    }
    return x1_5;
}
// ...

と正しくないコードが得られることを確認しました。

kmyk commented 2 years ago

たとえば

vector<int> func(vector<int> a) {
    for (int i = 0; i < n - 1; ++ i) {
        vector<int> b = a;
        b[i + 1] = a[i];
        a = b;
    }
    return a;
}

vector<int> func(vector<int> a) {
    for (int i = 0; i < n - 1; ++ i) {
        a[i + 1] = a[i];
    }
    return a;
}

に変換しないとだめなのだけど、これ無理じゃない? core から C++ への変換のときに情報が落ちてしまってて、その状態で添字の解析をやるのはしんどすぎるし、ある程度はやれたとしても不可能ケースが残ってしまう。 UnpackTuples.hs や MoveSemantics.hs の中身をすべて ToCore.hs に埋め込んで、core から C++ への変換のときにすべてを同時に最適にやるしかなさそう

https://github.com/kmyk/Jikka/pull/168#issuecomment-894584836

実装方針ミスが発覚したときの顔をしています 😇

riantkb commented 2 years ago

確かに core 言語で書かれたコードを等価でない cpp に変換してから頑張る、というのはかなり筋が悪そうな気がするので、core を cpp に変換するタイミングで頑張るしかなさそうですね…… 😇